Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6c98e88 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Improve PackageManager snapshot statistics" into sc-dev

parents 14af8e97 6e67ca77
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -174,9 +174,9 @@ option java_package com.android.server
# Disk usage stats for verifying quota correctness
3121 pm_package_stats (manual_time|2|3),(quota_time|2|3),(manual_data|2|2),(quota_data|2|2),(manual_cache|2|2),(quota_cache|2|2)
# Snapshot statistics
3130 pm_snapshot_stats (build_count|1|1),(reuse_count|1|1),(big_builds|1|1),(quick_rebuilds|1|1),(max_build_time|1|3),(cumm_build_time|1|3)
3130 pm_snapshot_stats (build_count|1|1),(reuse_count|1|1),(big_builds|1|1),(short_lived|1|1),(max_build_time|1|3),(cumm_build_time|2|3)
# Snapshot rebuild instance
3131 pm_snapshot_rebuild (build_time|1|3),(elapsed|1|3)
3131 pm_snapshot_rebuild (build_time|1|3),(lifetime|1|3)

# ---------------------------
# InputMethodManagerService.java
+1 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ public final class DumpState {
    public static final int DUMP_QUERIES = 1 << 26;
    public static final int DUMP_KNOWN_PACKAGES = 1 << 27;
    public static final int DUMP_PER_UID_READ_TIMEOUTS = 1 << 28;
    public static final int DUMP_SNAPSHOT_STATISTICS = 1 << 29;

    public static final int OPTION_SHOW_FILTERS = 1 << 0;
    public static final int OPTION_DUMP_ALL_COMPONENTS = 1 << 1;
+75 −133
Original line number Diff line number Diff line
@@ -1914,6 +1914,18 @@ public class PackageManagerService extends IPackageManager.Stub
     */
    private interface Computer {
        /**
         * Administrative statistics: record that the snapshot has been used.  Every call
         * to use() increments the usage counter.
         */
        void use();
        /**
         * Fetch the snapshot usage counter.
         * @return The number of times this snapshot was used.
         */
        int getUsed();
        @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType,
                int flags, @PrivateResolveFlags int privateResolveFlags, int filterCallingUid,
                int userId, boolean resolveForStart, boolean allowDynamicSplits);
@@ -2065,6 +2077,9 @@ public class PackageManagerService extends IPackageManager.Stub
     */
    private static class ComputerEngine implements Computer {
        // The administrative use counter.
        private int mUsed = 0;
        // Cached attributes.  The names in this class are the same as the
        // names in PackageManagerService; see that class for documentation.
        protected final Settings mSettings;
@@ -2157,6 +2172,20 @@ public class PackageManagerService extends IPackageManager.Stub
            mService = args.service;
        }
        /**
         * Record that the snapshot was used.
         */
        public void use() {
            mUsed++;
        }
        /**
         * Return the usage counter.
         */
        public int getUsed() {
            return mUsed;
        }
        public @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
                String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags,
                int filterCallingUid, int userId, boolean resolveForStart,
@@ -4885,121 +4914,11 @@ public class PackageManagerService extends IPackageManager.Stub
     */
    private final Object mSnapshotLock = new Object();
    // A counter of all queries that hit the current snapshot.
    @GuardedBy("mSnapshotLock")
    private int mSnapshotHits = 0;
    // A class to record snapshot statistics.
    private static class SnapshotStatistics {
        // A build time is "big" if it takes longer than 5ms.
        private static final long SNAPSHOT_BIG_BUILD_TIME_NS = TimeUnit.MILLISECONDS.toNanos(5);
        // A snapshot is in quick succession to the previous snapshot if it less than
        // 100ms since the previous snapshot.
        private static final long SNAPSHOT_QUICK_REBUILD_INTERVAL_NS =
                TimeUnit.MILLISECONDS.toNanos(100);
        // The interval between snapshot statistics logging, in ns.
        private static final long SNAPSHOT_LOG_INTERVAL_NS = TimeUnit.MINUTES.toNanos(10);
        // The throttle parameters for big build reporting.  Do not report more than this
        // many events in a single log interval.
        private static final int SNAPSHOT_BUILD_REPORT_LIMIT = 10;
        // The time the snapshot statistics were last logged.
        private long mStatisticsSent = 0;
        // The number of build events logged since the last periodic log.
        private int mLoggedBuilds = 0;
        // The time of the last build.
        private long mLastBuildTime = 0;
        // The number of times the snapshot has been rebuilt since the statistics were
        // last logged.
        private int mRebuilds = 0;
        // The number of times the snapshot has been used since it was rebuilt.
        private int mReused = 0;
        // The number of "big" build times since the last log.  "Big" is defined by
        // SNAPSHOT_BIG_BUILD_TIME.
        private int mBigBuilds = 0;
        // The number of quick rebuilds.  "Quick" is defined by
        // SNAPSHOT_QUICK_REBUILD_INTERVAL_NS.
        private int mQuickRebuilds = 0;
        // The time take to build a snapshot.  This is cumulative over the rebuilds recorded
        // in mRebuilds, so the average time to build a snapshot is given by
        // mBuildTimeNs/mRebuilds.
        private int mBuildTimeNs = 0;
        // The maximum build time since the last log.
        private long mMaxBuildTimeNs = 0;
        // The constant that converts ns to ms.  This is the divisor.
        private final long NS_TO_MS = TimeUnit.MILLISECONDS.toNanos(1);
        // Convert ns to an int ms.  The maximum range of this method is about 24 days.
        // There is no expectation that an event will take longer than that.
        private int nsToMs(long ns) {
            return (int) (ns / NS_TO_MS);
        }
        // The single method records a rebuild.  The "now" parameter is passed in because
        // the caller needed it to computer the duration, so pass it in to avoid
        // recomputing it.
        private void rebuild(long now, long done, int hits) {
            if (mStatisticsSent == 0) {
                mStatisticsSent = now;
            }
            final long elapsed = now - mLastBuildTime;
            final long duration = done - now;
            mLastBuildTime = now;
            if (mMaxBuildTimeNs < duration) {
                mMaxBuildTimeNs = duration;
            }
            mRebuilds++;
            mReused += hits;
            mBuildTimeNs += duration;
            boolean log_build = false;
            if (duration > SNAPSHOT_BIG_BUILD_TIME_NS) {
                log_build = true;
                mBigBuilds++;
            }
            if (elapsed < SNAPSHOT_QUICK_REBUILD_INTERVAL_NS) {
                log_build = true;
                mQuickRebuilds++;
            }
            if (log_build && mLoggedBuilds < SNAPSHOT_BUILD_REPORT_LIMIT) {
                EventLogTags.writePmSnapshotRebuild(nsToMs(duration), nsToMs(elapsed));
                mLoggedBuilds++;
            }
            final long log_interval = now - mStatisticsSent;
            if (log_interval >= SNAPSHOT_LOG_INTERVAL_NS) {
                EventLogTags.writePmSnapshotStats(mRebuilds, mReused,
                                                  mBigBuilds, mQuickRebuilds,
                                                  nsToMs(mMaxBuildTimeNs),
                                                  nsToMs(mBuildTimeNs));
                mStatisticsSent = now;
                mRebuilds = 0;
                mReused = 0;
                mBuildTimeNs = 0;
                mMaxBuildTimeNs = 0;
                mBigBuilds = 0;
                mQuickRebuilds = 0;
                mLoggedBuilds = 0;
            }
        }
    }
    // Snapshot statistics.
    @GuardedBy("mLock")
    private final SnapshotStatistics mSnapshotStatistics = new SnapshotStatistics();
    /**
     * The snapshot statistics.  These are collected to track performance and to identify
     * situations in which the snapshots are misbehaving.
     */
    private final SnapshotStatistics mSnapshotStatistics;
    // The snapshot disable/enable switch.  An image with the flag set true uses snapshots
    // and an image with the flag set false does not use snapshots.
@@ -5033,10 +4952,9 @@ public class PackageManagerService extends IPackageManager.Stub
            Computer c = mSnapshotComputer;
            if (sSnapshotCorked && (c != null)) {
                // Snapshots are corked, which means new ones should not be built right now.
                c.use();
                return c;
            }
            // Deliberately capture the value pre-increment
            final int hits = mSnapshotHits++;
            if (sSnapshotInvalid || (c == null)) {
                // The snapshot is invalid if it is marked as invalid or if it is null.  If it
                // is null, then it is currently being rebuilt by rebuildSnapshot().
@@ -5046,7 +4964,7 @@ public class PackageManagerService extends IPackageManager.Stub
                    // self-consistent (the lock is being held) and is current as of the time
                    // this function is entered.
                    if (sSnapshotInvalid) {
                        rebuildSnapshot(hits);
                        rebuildSnapshot();
                    }
                    // Guaranteed to be non-null.  mSnapshotComputer is only be set to null
@@ -5056,6 +4974,7 @@ public class PackageManagerService extends IPackageManager.Stub
                    c = mSnapshotComputer;
                }
            }
            c.use();
            return c;
        }
    }
@@ -5065,16 +4984,16 @@ public class PackageManagerService extends IPackageManager.Stub
     * threads from using the invalid computer until it is rebuilt.
     */
    @GuardedBy("mLock")
    private void rebuildSnapshot(int hits) {
        final long now = System.nanoTime();
    private void rebuildSnapshot() {
        final long now = SystemClock.currentTimeMicro();
        final int hits = mSnapshotComputer == null ? -1 : mSnapshotComputer.getUsed();
        mSnapshotComputer = null;
        sSnapshotInvalid = false;
        final Snapshot args = new Snapshot(Snapshot.SNAPPED);
        mSnapshotComputer = new ComputerEngine(args);
        final long done = System.nanoTime();
        final long done = SystemClock.currentTimeMicro();
        mSnapshotStatistics.rebuild(now, done, hits);
        mSnapshotHits = 0;
    }
    /**
@@ -6327,6 +6246,7 @@ public class PackageManagerService extends IPackageManager.Stub
        mSnapshotEnabled = false;
        mLiveComputer = createLiveComputer();
        mSnapshotComputer = null;
        mSnapshotStatistics = null;
        mPackages.putAll(testParams.packages);
        mEnableFreeCacheV2 = testParams.enableFreeCacheV2;
@@ -6479,6 +6399,7 @@ public class PackageManagerService extends IPackageManager.Stub
        mDomainVerificationManager = injector.getDomainVerificationManagerInternal();
        mDomainVerificationManager.setConnection(mDomainVerificationConnection);
        synchronized (mLock) {
            // Create the computer as soon as the state objects have been installed.  The
            // cached computer is the same as the live computer until the end of the
            // constructor, at which time the invalidation method updates it.  The cache is
@@ -6487,9 +6408,11 @@ public class PackageManagerService extends IPackageManager.Stub
            mSnapshotEnabled = SNAPSHOT_ENABLED;
            sSnapshotCorked = true;
            sSnapshotInvalid = true;
            mSnapshotStatistics = new SnapshotStatistics();
            mLiveComputer = createLiveComputer();
            mSnapshotComputer = null;
            registerObserver();
        }
        // CHECKSTYLE:OFF IndentationCheck
        synchronized (mInstallLock) {
@@ -23957,6 +23880,7 @@ public class PackageManagerService extends IPackageManager.Stub
                pw.println("    dexopt: dump dexopt state");
                pw.println("    compiler-stats: dump compiler statistics");
                pw.println("    service-permissions: dump permissions required by services");
                pw.println("    snapshot: dump snapshot statistics");
                pw.println("    known-packages: dump known packages");
                pw.println("    <package.name>: info about given package");
                return;
@@ -24105,6 +24029,8 @@ public class PackageManagerService extends IPackageManager.Stub
                dumpState.setDump(DumpState.DUMP_KNOWN_PACKAGES);
            } else if ("t".equals(cmd) || "timeouts".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_PER_UID_READ_TIMEOUTS);
            } else if ("snapshot".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_SNAPSHOT_STATISTICS);
            } else if ("write".equals(cmd)) {
                synchronized (mLock) {
                    writeSettingsLPrTEMP();
@@ -24433,6 +24359,22 @@ public class PackageManagerService extends IPackageManager.Stub
                pw.println(")");
            }
        }
        if (!checkin && dumpState.isDumping(DumpState.DUMP_SNAPSHOT_STATISTICS)) {
            pw.println("Snapshot statistics");
            if (!mSnapshotEnabled) {
                pw.println("  Snapshots disabled");
            } else {
                int hits = 0;
                synchronized (mSnapshotLock) {
                    if (mSnapshotComputer != null) {
                        hits = mSnapshotComputer.getUsed();
                    }
                }
                final long now = SystemClock.currentTimeMicro();
                mSnapshotStatistics.dump(pw, "  ", now, hits, true);
            }
        }
    }
    /**
+622 −0

File added.

Preview size limit exceeded, changes collapsed.