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

Commit 4ad88791 authored by Jing Ji's avatar Jing Ji
Browse files

Acquire the current timestamp within the procstats lock.

This CL fixes the race condition, where timestamps could be acquired
before going to the procstats-locked code section, while the ordering
of entering the code section isn't guaranteed anyhwere, thus a call
into procstats with an earlier timestamp could happen after a call
with a later timestamp, thus confuses the bookkeeping of procstats.

Bug: 194991626
Test: CtsAppTestCases
Change-Id: I8863c3738a97a4fcce881cb21f1db4df559a7b6b
parent eb7f4c07
Loading
Loading
Loading
Loading
+16 −11
Original line number Diff line number Diff line
@@ -853,7 +853,7 @@ public final class ActiveServices {
                final ServiceState stracker = r.getTracker();
                if (stracker != null) {
                    stracker.setForeground(true, mAm.mProcessStats.getMemFactorLocked(),
                            r.lastActivity);
                            SystemClock.uptimeMillis()); // Use current time, not lastActivity.
                }
            }
            mAm.mAppOpsService.startOperation(AppOpsManager.getToken(mAm.mAppOpsService),
@@ -1129,7 +1129,8 @@ public final class ActiveServices {
        synchronized (mAm.mProcessStats.mLock) {
            final ServiceState stracker = r.getTracker();
            if (stracker != null) {
                stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
                stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(),
                        SystemClock.uptimeMillis()); // Use current time, not lastActivity.
            }
        }
        r.callStart = false;
@@ -1961,7 +1962,8 @@ public final class ActiveServices {
                                final ServiceState stracker = r.getTracker();
                                if (stracker != null) {
                                    stracker.setForeground(true,
                                            mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
                                            mAm.mProcessStats.getMemFactorLocked(),
                                            SystemClock.uptimeMillis());
                                }
                            }
                        } else {
@@ -2828,7 +2830,7 @@ public final class ActiveServices {
                        final ServiceState stracker = s.getTracker();
                        if (stracker != null) {
                            stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(),
                                    s.lastActivity);
                                    SystemClock.uptimeMillis());
                        }
                    }
                }
@@ -3494,14 +3496,14 @@ public final class ActiveServices {
            timeoutNeeded = false;
        }

        long now = SystemClock.uptimeMillis();
        ProcessServiceRecord psr;
        if (r.executeNesting == 0) {
            r.executeFg = fg;
            synchronized (mAm.mProcessStats.mLock) {
                final ServiceState stracker = r.getTracker();
                if (stracker != null) {
                    stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
                    stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(),
                            SystemClock.uptimeMillis());
                }
            }
            if (r.app != null) {
@@ -3532,7 +3534,7 @@ public final class ActiveServices {
        }
        r.executeFg |= fg;
        r.executeNesting++;
        r.executingStart = now;
        r.executingStart = SystemClock.uptimeMillis();
        return oomAdjusted;
    }

@@ -3719,7 +3721,8 @@ public final class ActiveServices {
            if (oldPosInRestarting == -1) {
                r.createdFromFg = false;
                synchronized (mAm.mProcessStats.mLock) {
                    r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
                    r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(),
                            SystemClock.uptimeMillis());
                }
            }
            boolean added = false;
@@ -4485,7 +4488,6 @@ public final class ActiveServices {
            }
        }

        final long now = SystemClock.uptimeMillis();
        // Check to see if the service had been started as foreground, but being
        // brought down before actually showing a notification.  That is not allowed.
        if (r.fgRequired) {
@@ -4496,7 +4498,8 @@ public final class ActiveServices {
            synchronized (mAm.mProcessStats.mLock) {
                ServiceState stracker = r.getTracker();
                if (stracker != null) {
                    stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(), now);
                    stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
                            SystemClock.uptimeMillis());
                }
            }
            mAm.mAppOpsService.finishOperation(AppOpsManager.getToken(mAm.mAppOpsService),
@@ -4557,7 +4560,8 @@ public final class ActiveServices {
            synchronized (mAm.mProcessStats.mLock) {
                ServiceState stracker = r.getTracker();
                if (stracker != null) {
                    stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(), now);
                    stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
                            SystemClock.uptimeMillis());
                }
            }
            mAm.mAppOpsService.finishOperation(
@@ -4629,6 +4633,7 @@ public final class ActiveServices {
        synchronized (mAm.mProcessStats.mLock) {
            final int memFactor = mAm.mProcessStats.getMemFactorLocked();
            if (r.tracker != null) {
                final long now = SystemClock.uptimeMillis();
                r.tracker.setStarted(false, memFactor, now);
                r.tracker.setBound(false, memFactor, now);
                if (r.executeNesting == 0) {
+2 −2
Original line number Diff line number Diff line
@@ -14684,10 +14684,10 @@ public class ActivityManagerService extends IActivityManager.Stub
    }
    @GuardedBy(anyOf = {"this", "mProcLock"})
    final void setProcessTrackerStateLOSP(ProcessRecord proc, int memFactor, long now) {
    final void setProcessTrackerStateLOSP(ProcessRecord proc, int memFactor) {
        if (proc.getThread() != null) {
            proc.mProfile.setProcessTrackerState(
                    proc.mState.getReportedProcState(), memFactor, now);
                    proc.mState.getReportedProcState(), memFactor);
        }
    }
+4 −3
Original line number Diff line number Diff line
@@ -953,7 +953,6 @@ public class AppProfiler {

    @GuardedBy({"mService", "mProcLock"})
    boolean updateLowMemStateLSP(int numCached, int numEmpty, int numTrimming) {
        final long now = SystemClock.uptimeMillis();
        int memFactor;
        if (mLowMemDetector != null && mLowMemDetector.isAvailable()) {
            memFactor = mLowMemDetector.getMemFactor();
@@ -1008,7 +1007,9 @@ public class AppProfiler {
        mLastNumProcesses = mService.mProcessList.getLruSizeLOSP();
        boolean allChanged;
        int trackerMemFactor;
        final long now;
        synchronized (mService.mProcessStats.mLock) {
            now = SystemClock.uptimeMillis();
            allChanged = mService.mProcessStats.setMemFactorLocked(memFactor,
                    mService.mAtmInternal == null || !mService.mAtmInternal.isSleeping(), now);
            trackerMemFactor = mService.mProcessStats.getMemFactorLocked();
@@ -1044,7 +1045,7 @@ public class AppProfiler {
                final int curProcState = state.getCurProcState();
                IApplicationThread thread;
                if (allChanged || state.hasProcStateChanged()) {
                    mService.setProcessTrackerStateLOSP(app, trackerMemFactor, now);
                    mService.setProcessTrackerStateLOSP(app, trackerMemFactor);
                    state.setProcStateChanged(false);
                }
                trimMemoryUiHiddenIfNecessaryLSP(app);
@@ -1113,7 +1114,7 @@ public class AppProfiler {
                final IApplicationThread thread;
                final ProcessStateRecord state = app.mState;
                if (allChanged || state.hasProcStateChanged()) {
                    mService.setProcessTrackerStateLOSP(app, trackerMemFactor, now);
                    mService.setProcessTrackerStateLOSP(app, trackerMemFactor);
                    state.setProcStateChanged(false);
                }
                trimMemoryUiHiddenIfNecessaryLSP(app);
+3 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.app.IServiceConnection;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.os.SystemClock;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoUtils;
@@ -158,10 +159,10 @@ final class ConnectionRecord {
        }
    }

    public void trackProcState(int procState, int seq, long now) {
    public void trackProcState(int procState, int seq) {
        if (association != null) {
            synchronized (mProcStatsLock) {
                association.trackProcState(procState, seq, now);
                association.trackProcState(procState, seq, SystemClock.uptimeMillis());
            }
        }
    }
+5 −2
Original line number Diff line number Diff line
@@ -98,10 +98,13 @@ public final class ContentProviderConnection extends Binder {
        }
    }

    public void trackProcState(int procState, int seq, long now) {
    /**
     * Track the given proc state change.
     */
    public void trackProcState(int procState, int seq) {
        if (association != null) {
            synchronized (mProcStatsLock) {
                association.trackProcState(procState, seq, now);
                association.trackProcState(procState, seq, SystemClock.uptimeMillis());
            }
        }
    }
Loading