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

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

Merge "ActivityManagerService: explicitly break connection cycles" into pi-dev

parents 147ef6b1 b52f000f
Loading
Loading
Loading
Loading
+87 −10
Original line number Diff line number Diff line
@@ -22995,18 +22995,27 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
    }
    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
    private final boolean computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
            boolean doingAll, long now) {
        if (mAdjSeq == app.adjSeq) {
            // This adjustment has already been computed.
            return app.curRawAdj;
            if (app.adjSeq == app.completedAdjSeq) {
                // This adjustment has already been computed successfully.
                return false;
            } else {
                // The process is being computed, so there is a cycle. We cannot
                // rely on this process's state.
                app.containsCycle = true;
                return false;
            }
        }
        if (app.thread == null) {
            app.adjSeq = mAdjSeq;
            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
            app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ;
            app.completedAdjSeq = app.adjSeq;
            return false;
        }
        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
@@ -23019,6 +23028,8 @@ public class ActivityManagerService extends IActivityManager.Stub
        final int appUid = app.info.uid;
        final int logUid = mCurOomAdjUid;
        int prevAppAdj = app.curAdj;
        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
            // The max adjustment doesn't allow this app to be anything
            // below foreground, so it is not worth doing work for it.
@@ -23063,7 +23074,10 @@ public class ActivityManagerService extends IActivityManager.Stub
                  app.curSchedGroup = ProcessList.SCHED_GROUP_RESTRICTED;
              }
            }
            return (app.curAdj=app.maxAdj);
            app.curAdj = app.maxAdj;
            app.completedAdjSeq = app.adjSeq;
            // if curAdj is less than prevAppAdj, then this process was promoted
            return app.curAdj < prevAppAdj;
        }
        app.systemNoUi = false;
@@ -23075,6 +23089,8 @@ public class ActivityManagerService extends IActivityManager.Stub
        int adj;
        int schedGroup;
        int procState;
        int cachedAdjSeq;
        boolean foregroundActivities = false;
        mTmpBroadcastQueue.clear();
        if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) {
@@ -23388,9 +23404,9 @@ public class ActivityManagerService extends IActivityManager.Stub
        // there are applications dependent on our services or providers, but
        // this gives us a baseline and makes sure we don't get into an
        // infinite recursion.
        app.adjSeq = mAdjSeq;
        app.curRawAdj = adj;
        app.hasStartedServices = false;
        app.adjSeq = mAdjSeq;
        if (mBackupTarget != null && app == mBackupTarget.app) {
            // If possible we want to avoid killing apps while they're being backed up
@@ -23489,8 +23505,15 @@ public class ActivityManagerService extends IActivityManager.Stub
                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
                        ProcessRecord client = cr.binding.client;
                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
                                TOP_APP, doingAll, now);
                        computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
                        if (client.containsCycle) {
                            // We've detected a cycle. We should ignore this connection and allow
                            // this process to retry computeOomAdjLocked later in case a later-checked
                            // connection from a client  would raise its priority legitimately.
                            app.containsCycle = true;
                            continue;
                        }
                        int clientAdj = client.curRawAdj;
                        int clientProcState = client.curProcState;
                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
                            // If the other app is cached for any reason, for purposes here
@@ -23709,7 +23732,15 @@ public class ActivityManagerService extends IActivityManager.Stub
                    // Being our own client is not interesting.
                    continue;
                }
                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
                computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
                if (client.containsCycle) {
                    // We've detected a cycle. We should ignore this connection and allow
                    // this process to retry computeOomAdjLocked later in case a later-checked
                    // connection from a client  would raise its priority legitimately.
                    app.containsCycle = true;
                    continue;
                }
                int clientAdj = client.curRawAdj;
                int clientProcState = client.curProcState;
                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
                    // If the other app is cached for any reason, for purposes here
@@ -23937,8 +23968,10 @@ public class ActivityManagerService extends IActivityManager.Stub
        app.curSchedGroup = schedGroup;
        app.curProcState = procState;
        app.foregroundActivities = foregroundActivities;
        app.completedAdjSeq = mAdjSeq;
        return app.curRawAdj;
        // if curAdj is less than prevAppAdj, then this process was promoted
        return app.curAdj < prevAppAdj;
    }
    /**
@@ -24912,12 +24945,23 @@ public class ActivityManagerService extends IActivityManager.Stub
        int nextCachedAdj = curCachedAdj+1;
        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
        int nextEmptyAdj = curEmptyAdj+2;
        boolean retryCycles = false;
        // need to reset cycle state before calling computeOomAdjLocked because of service connections
        for (int i=N-1; i>=0; i--) {
            ProcessRecord app = mLruProcesses.get(i);
            app.containsCycle = false;
        }
        for (int i=N-1; i>=0; i--) {
            ProcessRecord app = mLruProcesses.get(i);
            if (!app.killedByAm && app.thread != null) {
                app.procStateChanged = false;
                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
                // if any app encountered a cycle, we need to perform an additional loop later
                retryCycles |= app.containsCycle;
                // If we haven't yet assigned the final cached adj
                // to the process, do that now.
                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
@@ -24971,6 +25015,39 @@ public class ActivityManagerService extends IActivityManager.Stub
                    }
                }
            }
        }
        // Cycle strategy:
        // - Retry computing any process that has encountered a cycle.
        // - Continue retrying until no process was promoted.
        // - Iterate from least important to most important.
        int cycleCount = 0;
        while (retryCycles) {
            cycleCount++;
            retryCycles = false;
            for (int i=0; i<N; i++) {
                ProcessRecord app = mLruProcesses.get(i);
                if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
                    app.adjSeq--;
                    app.completedAdjSeq--;
                }
            }
            for (int i=0; i<N; i++) {
                ProcessRecord app = mLruProcesses.get(i);
                if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
                    if (computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now)) {
                        retryCycles = true;
                    }
                }
            }
        }
        for (int i=N-1; i>=0; i--) {
            ProcessRecord app = mLruProcesses.get(i);
            if (!app.killedByAm && app.thread != null) {
                applyOomAdjLocked(app, true, now, nowElapsed);
                // Count the number of process types.
+2 −0
Original line number Diff line number Diff line
@@ -149,6 +149,8 @@ final class ProcessRecord {
    String waitingToKill;       // Process is waiting to be killed when in the bg, and reason
    Object forcingToImportant;  // Token that is forcing this process to be important
    int adjSeq;                 // Sequence id for identifying oom_adj assignment cycles
    int completedAdjSeq;        // Sequence id for identifying oom_adj assignment cycles
    boolean containsCycle;      // Whether this app has encountered a cycle in the most recent update
    int lruSeq;                 // Sequence id for identifying LRU update cycles
    CompatibilityInfo compat;   // last used compatibility mode
    IBinder.DeathRecipient deathRecipient; // Who is watching for the death.