summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jing Ji <jji@google.com> 2020-08-06 03:29:52 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-08-06 03:29:52 +0000
commit65ed484e5740a99f06f9a1551c324efb68bc7c4b (patch)
tree7fbba6c4037f6aa902855294efd34e33badca01b
parent8bb5d401ea5f2584405075179a759a5aa2f77081 (diff)
parentbee7f641227224a2d788ee5ac84f2afb88ff8ad7 (diff)
Merge "Use a different lock for the ProcessStatsService"
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java24
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java14
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java158
-rw-r--r--services/core/java/com/android/server/am/ProcessStatsService.java287
-rw-r--r--services/core/java/com/android/server/am/ServiceRecord.java8
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java3
6 files changed, 295 insertions, 199 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5296f752c0f8..5555650d9be2 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1962,7 +1962,7 @@ public class ActivityManagerService extends IActivityManager.Stub
nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
}
memInfo.readMemInfo();
- synchronized (ActivityManagerService.this) {
+ synchronized (mProcessStats.mLock) {
if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
+ (SystemClock.uptimeMillis()-start) + "ms");
final long cachedKb = memInfo.getCachedSizeKb();
@@ -7054,9 +7054,7 @@ public class ActivityManagerService extends IActivityManager.Stub
mUsageStatsService.prepareShutdown();
}
mBatteryStatsService.shutdown();
- synchronized (this) {
- mProcessStats.shutdownLocked();
- }
+ mProcessStats.shutdown();
return timedout;
}
@@ -12358,7 +12356,7 @@ public class ActivityManagerService extends IActivityManager.Stub
MemInfoReader memInfo = new MemInfoReader();
memInfo.readMemInfo();
if (nativeProcTotalPss > 0) {
- synchronized (this) {
+ synchronized (mProcessStats.mLock) {
final long cachedKb = memInfo.getCachedSizeKb();
final long freeKb = memInfo.getFreeSizeKb();
final long zramKb = memInfo.getZramTotalSizeKb();
@@ -12940,7 +12938,7 @@ public class ActivityManagerService extends IActivityManager.Stub
MemInfoReader memInfo = new MemInfoReader();
memInfo.readMemInfo();
if (nativeProcTotalPss > 0) {
- synchronized (this) {
+ synchronized (mProcessStats.mLock) {
final long cachedKb = memInfo.getCachedSizeKb();
final long freeKb = memInfo.getFreeSizeKb();
final long zramKb = memInfo.getZramTotalSizeKb();
@@ -16511,9 +16509,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override public void run() {
- synchronized (mService) {
- mProcessStats.writeStateAsyncLocked();
- }
+ mProcessStats.writeStateAsync();
}
}
@@ -16563,9 +16559,13 @@ public class ActivityManagerService extends IActivityManager.Stub
}
mLastMemoryLevel = memFactor;
mLastNumProcesses = mProcessList.getLruSizeLocked();
- boolean allChanged = mProcessStats.setMemFactorLocked(
- memFactor, mAtmInternal != null ? !mAtmInternal.isSleeping() : true, now);
- final int trackerMemFactor = mProcessStats.getMemFactorLocked();
+ boolean allChanged;
+ int trackerMemFactor;
+ synchronized (mProcessStats.mLock) {
+ allChanged = mProcessStats.setMemFactorLocked(
+ memFactor, mAtmInternal != null ? !mAtmInternal.isSleeping() : true, now);
+ trackerMemFactor = mProcessStats.getMemFactorLocked();
+ }
if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
if (mLowRamStartTime == 0) {
mLowRamStartTime = now;
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index f0343e1d807c..bf15f1737cfc 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -659,13 +659,15 @@ public final class OomAdjuster {
updateUidsLocked(activeUids, nowElapsed);
- if (mService.mProcessStats.shouldWriteNowLocked(now)) {
- mService.mHandler.post(new ActivityManagerService.ProcStatsRunnable(mService,
- mService.mProcessStats));
- }
+ synchronized (mService.mProcessStats.mLock) {
+ if (mService.mProcessStats.shouldWriteNowLocked(now)) {
+ mService.mHandler.post(new ActivityManagerService.ProcStatsRunnable(mService,
+ mService.mProcessStats));
+ }
- // Run this after making sure all procstates are updated.
- mService.mProcessStats.updateTrackingAssociationsLocked(mAdjSeq, now);
+ // Run this after making sure all procstates are updated.
+ mService.mProcessStats.updateTrackingAssociationsLocked(mAdjSeq, now);
+ }
if (DEBUG_OOM_ADJ) {
final long duration = SystemClock.uptimeMillis() - now;
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 1647fdaa57b6..e3e13391a8b0 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -673,30 +673,33 @@ class ProcessRecord implements WindowProcessListener {
public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
if (thread == null) {
- final ProcessState origBase = baseProcessTracker;
- if (origBase != null) {
- origBase.setState(ProcessStats.STATE_NOTHING,
- tracker.getMemFactorLocked(), SystemClock.uptimeMillis(), pkgList.mPkgList);
- for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) {
- FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_STATE_CHANGED,
- uid, processName, pkgList.keyAt(ipkg),
- ActivityManager.processStateAmToProto(ProcessStats.STATE_NOTHING),
- pkgList.valueAt(ipkg).appVersion);
- }
- origBase.makeInactive();
- }
- baseProcessTracker = tracker.getProcessStateLocked(info.packageName, info.uid,
- info.longVersionCode, processName);
- baseProcessTracker.makeActive();
- for (int i=0; i<pkgList.size(); i++) {
- ProcessStats.ProcessStateHolder holder = pkgList.valueAt(i);
- if (holder.state != null && holder.state != origBase) {
- holder.state.makeInactive();
+ synchronized (tracker.mLock) {
+ final ProcessState origBase = baseProcessTracker;
+ if (origBase != null) {
+ origBase.setState(ProcessStats.STATE_NOTHING,
+ tracker.getMemFactorLocked(), SystemClock.uptimeMillis(),
+ pkgList.mPkgList);
+ for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) {
+ FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_STATE_CHANGED,
+ uid, processName, pkgList.keyAt(ipkg),
+ ActivityManager.processStateAmToProto(ProcessStats.STATE_NOTHING),
+ pkgList.valueAt(ipkg).appVersion);
+ }
+ origBase.makeInactive();
}
- tracker.updateProcessStateHolderLocked(holder, pkgList.keyAt(i), info.uid,
+ baseProcessTracker = tracker.getProcessStateLocked(info.packageName, info.uid,
info.longVersionCode, processName);
- if (holder.state != baseProcessTracker) {
- holder.state.makeActive();
+ baseProcessTracker.makeActive();
+ for (int i = 0, ipkg = pkgList.size(); i < ipkg; i++) {
+ ProcessStats.ProcessStateHolder holder = pkgList.valueAt(i);
+ if (holder.state != null && holder.state != origBase) {
+ holder.state.makeInactive();
+ }
+ tracker.updateProcessStateHolderLocked(holder, pkgList.keyAt(i), info.uid,
+ info.longVersionCode, processName);
+ if (holder.state != baseProcessTracker) {
+ holder.state.makeActive();
+ }
}
}
}
@@ -707,27 +710,30 @@ class ProcessRecord implements WindowProcessListener {
public void makeInactive(ProcessStatsService tracker) {
thread = null;
mWindowProcessController.setThread(null);
- final ProcessState origBase = baseProcessTracker;
- if (origBase != null) {
+ synchronized (tracker.mLock) {
+ final ProcessState origBase = baseProcessTracker;
if (origBase != null) {
- origBase.setState(ProcessStats.STATE_NOTHING,
- tracker.getMemFactorLocked(), SystemClock.uptimeMillis(), pkgList.mPkgList);
- for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) {
- FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_STATE_CHANGED,
- uid, processName, pkgList.keyAt(ipkg),
- ActivityManager.processStateAmToProto(ProcessStats.STATE_NOTHING),
- pkgList.valueAt(ipkg).appVersion);
+ if (origBase != null) {
+ origBase.setState(ProcessStats.STATE_NOTHING,
+ tracker.getMemFactorLocked(), SystemClock.uptimeMillis(),
+ pkgList.mPkgList);
+ for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) {
+ FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_STATE_CHANGED,
+ uid, processName, pkgList.keyAt(ipkg),
+ ActivityManager.processStateAmToProto(ProcessStats.STATE_NOTHING),
+ pkgList.valueAt(ipkg).appVersion);
+ }
+ origBase.makeInactive();
}
- origBase.makeInactive();
- }
- baseProcessTracker = null;
- for (int i=0; i<pkgList.size(); i++) {
- ProcessStats.ProcessStateHolder holder = pkgList.valueAt(i);
- if (holder.state != null && holder.state != origBase) {
- holder.state.makeInactive();
+ baseProcessTracker = null;
+ for (int i = 0, ipkg = pkgList.size(); i < ipkg; i++) {
+ ProcessStats.ProcessStateHolder holder = pkgList.valueAt(i);
+ if (holder.state != null && holder.state != origBase) {
+ holder.state.makeInactive();
+ }
+ holder.pkg = null;
+ holder.state = null;
}
- holder.pkg = null;
- holder.state = null;
}
}
}
@@ -1026,17 +1032,19 @@ class ProcessRecord implements WindowProcessListener {
*/
public boolean addPackage(String pkg, long versionCode, ProcessStatsService tracker) {
if (!pkgList.containsKey(pkg)) {
- ProcessStats.ProcessStateHolder holder = new ProcessStats.ProcessStateHolder(
- versionCode);
- if (baseProcessTracker != null) {
- tracker.updateProcessStateHolderLocked(holder, pkg, info.uid, versionCode,
- processName);
- pkgList.put(pkg, holder);
- if (holder.state != baseProcessTracker) {
- holder.state.makeActive();
+ synchronized (tracker.mLock) {
+ ProcessStats.ProcessStateHolder holder = new ProcessStats.ProcessStateHolder(
+ versionCode);
+ if (baseProcessTracker != null) {
+ tracker.updateProcessStateHolderLocked(holder, pkg, info.uid, versionCode,
+ processName);
+ pkgList.put(pkg, holder);
+ if (holder.state != baseProcessTracker) {
+ holder.state.makeActive();
+ }
+ } else {
+ pkgList.put(pkg, holder);
}
- } else {
- pkgList.put(pkg, holder);
}
return true;
}
@@ -1072,31 +1080,33 @@ class ProcessRecord implements WindowProcessListener {
public void resetPackageList(ProcessStatsService tracker) {
final int N = pkgList.size();
if (baseProcessTracker != null) {
- long now = SystemClock.uptimeMillis();
- baseProcessTracker.setState(ProcessStats.STATE_NOTHING,
- tracker.getMemFactorLocked(), now, pkgList.mPkgList);
- for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) {
- FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_STATE_CHANGED,
- uid, processName, pkgList.keyAt(ipkg),
- ActivityManager.processStateAmToProto(ProcessStats.STATE_NOTHING),
- pkgList.valueAt(ipkg).appVersion);
- }
- if (N != 1) {
- for (int i=0; i<N; i++) {
- ProcessStats.ProcessStateHolder holder = pkgList.valueAt(i);
- if (holder.state != null && holder.state != baseProcessTracker) {
- holder.state.makeInactive();
- }
-
+ synchronized (tracker.mLock) {
+ long now = SystemClock.uptimeMillis();
+ baseProcessTracker.setState(ProcessStats.STATE_NOTHING,
+ tracker.getMemFactorLocked(), now, pkgList.mPkgList);
+ for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) {
+ FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_STATE_CHANGED,
+ uid, processName, pkgList.keyAt(ipkg),
+ ActivityManager.processStateAmToProto(ProcessStats.STATE_NOTHING),
+ pkgList.valueAt(ipkg).appVersion);
}
- pkgList.clear();
- ProcessStats.ProcessStateHolder holder = new ProcessStats.ProcessStateHolder(
- info.longVersionCode);
- tracker.updateProcessStateHolderLocked(holder, info.packageName, info.uid,
- info.longVersionCode, processName);
- pkgList.put(info.packageName, holder);
- if (holder.state != baseProcessTracker) {
- holder.state.makeActive();
+ if (N != 1) {
+ for (int i = 0; i < N; i++) {
+ ProcessStats.ProcessStateHolder holder = pkgList.valueAt(i);
+ if (holder.state != null && holder.state != baseProcessTracker) {
+ holder.state.makeInactive();
+ }
+
+ }
+ pkgList.clear();
+ ProcessStats.ProcessStateHolder holder = new ProcessStats.ProcessStateHolder(
+ info.longVersionCode);
+ tracker.updateProcessStateHolderLocked(holder, info.packageName, info.uid,
+ info.longVersionCode, processName);
+ pkgList.put(info.packageName, holder);
+ if (holder.state != baseProcessTracker) {
+ holder.state.makeActive();
+ }
}
}
} else if (N != 1) {
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index a168af5ad842..4e8c386a3c66 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -71,33 +71,62 @@ public final class ProcessStatsService extends IProcessStats.Stub {
final ActivityManagerService mAm;
final File mBaseDir;
- ProcessStats mProcessStats;
+
+ // Note: The locking order of the below 3 locks should be:
+ // mLock, mPendingWriteLock, mFileLock
+
+ // The lock object to protect the internal state/structures
+ final Object mLock = new Object();
+
+ // The lock object to protect the access to pending writes
+ final Object mPendingWriteLock = new Object();
+
+ // The lock object to protect the access to all of the file read/write
+ final ReentrantLock mFileLock = new ReentrantLock();
+
+ @GuardedBy("mLock")
+ final ProcessStats mProcessStats;
+
+ @GuardedBy("mFileLock")
AtomicFile mFile;
+
+ @GuardedBy("mLock")
boolean mCommitPending;
+
+ @GuardedBy("mLock")
boolean mShuttingDown;
+
+ @GuardedBy("mLock")
int mLastMemOnlyState = -1;
boolean mMemFactorLowered;
- final ReentrantLock mWriteLock = new ReentrantLock();
- final Object mPendingWriteLock = new Object();
+ @GuardedBy("mPendingWriteLock")
AtomicFile mPendingWriteFile;
+
+ @GuardedBy("mPendingWriteLock")
Parcel mPendingWrite;
+
+ @GuardedBy("mPendingWriteLock")
boolean mPendingWriteCommitted;
+
+ @GuardedBy("mLock")
long mLastWriteTime;
/** For CTS to inject the screen state. */
- @GuardedBy("mAm")
+ @GuardedBy("mLock")
Boolean mInjectedScreenState;
public ProcessStatsService(ActivityManagerService am, File file) {
mAm = am;
mBaseDir = file;
mBaseDir.mkdirs();
- mProcessStats = new ProcessStats(true);
- updateFile();
+ synchronized (mLock) {
+ mProcessStats = new ProcessStats(true);
+ updateFileLocked();
+ }
SystemProperties.addChangeCallback(new Runnable() {
@Override public void run() {
- synchronized (mAm) {
+ synchronized (mLock) {
if (mProcessStats.evaluateSystemProperties(false)) {
mProcessStats.mFlags |= ProcessStats.FLAG_SYSPROPS;
writeStateLocked(true, true);
@@ -121,32 +150,33 @@ public final class ProcessStatsService extends IProcessStats.Stub {
}
}
- @GuardedBy("mAm")
- public void updateProcessStateHolderLocked(ProcessStats.ProcessStateHolder holder,
+ @GuardedBy("mLock")
+ void updateProcessStateHolderLocked(ProcessStats.ProcessStateHolder holder,
String packageName, int uid, long versionCode, String processName) {
holder.pkg = mProcessStats.getPackageStateLocked(packageName, uid, versionCode);
holder.state = mProcessStats.getProcessStateLocked(holder.pkg, processName);
}
- @GuardedBy("mAm")
- public ProcessState getProcessStateLocked(String packageName,
+ @GuardedBy("mLock")
+ ProcessState getProcessStateLocked(String packageName,
int uid, long versionCode, String processName) {
return mProcessStats.getProcessStateLocked(packageName, uid, versionCode, processName);
}
- @GuardedBy("mAm")
- public ServiceState getServiceStateLocked(String packageName, int uid,
+ ServiceState getServiceState(String packageName, int uid,
long versionCode, String processName, String className) {
- return mProcessStats.getServiceStateLocked(packageName, uid, versionCode, processName,
- className);
+ synchronized (mLock) {
+ return mProcessStats.getServiceStateLocked(packageName, uid, versionCode, processName,
+ className);
+ }
}
- public boolean isMemFactorLowered() {
+ boolean isMemFactorLowered() {
return mMemFactorLowered;
}
- @GuardedBy("mAm")
- public boolean setMemFactorLocked(int memFactor, boolean screenOn, long now) {
+ @GuardedBy("mLock")
+ boolean setMemFactorLocked(int memFactor, boolean screenOn, long now) {
mMemFactorLowered = memFactor < mLastMemOnlyState;
mLastMemOnlyState = memFactor;
if (mInjectedScreenState != null) {
@@ -184,24 +214,24 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return false;
}
- @GuardedBy("mAm")
- public int getMemFactorLocked() {
+ @GuardedBy("mLock")
+ int getMemFactorLocked() {
return mProcessStats.mMemFactor != ProcessStats.STATE_NOTHING ? mProcessStats.mMemFactor : 0;
}
- @GuardedBy("mAm")
- public void addSysMemUsageLocked(long cachedMem, long freeMem, long zramMem, long kernelMem,
+ @GuardedBy("mLock")
+ void addSysMemUsageLocked(long cachedMem, long freeMem, long zramMem, long kernelMem,
long nativeMem) {
mProcessStats.addSysMemUsage(cachedMem, freeMem, zramMem, kernelMem, nativeMem);
}
- @GuardedBy("mAm")
- public void updateTrackingAssociationsLocked(int curSeq, long now) {
+ @GuardedBy("mLock")
+ void updateTrackingAssociationsLocked(int curSeq, long now) {
mProcessStats.updateTrackingAssociationsLocked(curSeq, now);
}
- @GuardedBy("mAm")
- public boolean shouldWriteNowLocked(long now) {
+ @GuardedBy("mLock")
+ boolean shouldWriteNowLocked(long now) {
if (now > (mLastWriteTime+WRITE_PERIOD)) {
if (SystemClock.elapsedRealtime()
> (mProcessStats.mTimePeriodStartRealtime+ProcessStats.COMMIT_PERIOD) &&
@@ -214,25 +244,27 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return false;
}
- @GuardedBy("mAm")
- public void shutdownLocked() {
+ void shutdown() {
Slog.w(TAG, "Writing process stats before shutdown...");
- mProcessStats.mFlags |= ProcessStats.FLAG_SHUTDOWN;
- writeStateSyncLocked();
- mShuttingDown = true;
+ synchronized (mLock) {
+ mProcessStats.mFlags |= ProcessStats.FLAG_SHUTDOWN;
+ writeStateSyncLocked();
+ mShuttingDown = true;
+ }
}
- @GuardedBy("mAm")
- public void writeStateAsyncLocked() {
- writeStateLocked(false);
+ void writeStateAsync() {
+ synchronized (mLock) {
+ writeStateLocked(false);
+ }
}
- @GuardedBy("mAm")
- public void writeStateSyncLocked() {
+ @GuardedBy("mLock")
+ private void writeStateSyncLocked() {
writeStateLocked(true);
}
- @GuardedBy("mAm")
+ @GuardedBy("mLock")
private void writeStateLocked(boolean sync) {
if (mShuttingDown) {
return;
@@ -242,8 +274,8 @@ public final class ProcessStatsService extends IProcessStats.Stub {
writeStateLocked(sync, commitPending);
}
- @GuardedBy("mAm")
- public void writeStateLocked(boolean sync, final boolean commit) {
+ @GuardedBy("mLock")
+ private void writeStateLocked(boolean sync, final boolean commit) {
final long totalTime;
synchronized (mPendingWriteLock) {
final long now = SystemClock.uptimeMillis();
@@ -255,13 +287,13 @@ public final class ProcessStatsService extends IProcessStats.Stub {
mProcessStats.mFlags |= ProcessStats.FLAG_COMPLETE;
}
mProcessStats.writeToParcel(mPendingWrite, 0);
- mPendingWriteFile = new AtomicFile(mFile.getBaseFile());
+ mPendingWriteFile = new AtomicFile(getCurrentFile());
mPendingWriteCommitted = commit;
}
if (commit) {
mProcessStats.resetSafely();
- updateFile();
- mAm.requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
+ updateFileLocked();
+ scheduleRequestPssAllProcs(true, false);
}
mLastWriteTime = SystemClock.uptimeMillis();
totalTime = SystemClock.uptimeMillis() - now;
@@ -279,14 +311,37 @@ public final class ProcessStatsService extends IProcessStats.Stub {
performWriteState(totalTime);
}
- private void updateFile() {
- mFile = new AtomicFile(new File(mBaseDir, STATE_FILE_PREFIX
- + mProcessStats.mTimePeriodStartClockStr + STATE_FILE_SUFFIX));
+ private void scheduleRequestPssAllProcs(boolean always, boolean memLowered) {
+ mAm.mHandler.post(() -> {
+ synchronized (mAm) {
+ mAm.requestPssAllProcsLocked(SystemClock.uptimeMillis(), always, memLowered);
+ }
+ });
+ }
+
+ @GuardedBy("mLock")
+ private void updateFileLocked() {
+ mFileLock.lock();
+ try {
+ mFile = new AtomicFile(new File(mBaseDir, STATE_FILE_PREFIX
+ + mProcessStats.mTimePeriodStartClockStr + STATE_FILE_SUFFIX));
+ } finally {
+ mFileLock.unlock();
+ }
mLastWriteTime = SystemClock.uptimeMillis();
}
- void performWriteState(long initialTime) {
- if (DEBUG) Slog.d(TAG, "Performing write to " + mFile.getBaseFile());
+ private File getCurrentFile() {
+ mFileLock.lock();
+ try {
+ return mFile.getBaseFile();
+ } finally {
+ mFileLock.unlock();
+ }
+ }
+
+ private void performWriteState(long initialTime) {
+ if (DEBUG) Slog.d(TAG, "Performing write to " + getCurrentFile());
Parcel data;
AtomicFile file;
synchronized (mPendingWriteLock) {
@@ -298,7 +353,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
}
mPendingWrite = null;
mPendingWriteFile = null;
- mWriteLock.lock();
+ mFileLock.lock();
}
final long startTime = SystemClock.uptimeMillis();
@@ -316,13 +371,13 @@ public final class ProcessStatsService extends IProcessStats.Stub {
file.failWrite(stream);
} finally {
data.recycle();
- trimHistoricStatesWriteLocked();
- mWriteLock.unlock();
+ trimHistoricStatesWriteLF();
+ mFileLock.unlock();
}
}
- @GuardedBy("mAm")
- boolean readLocked(ProcessStats stats, AtomicFile file) {
+ @GuardedBy("mFileLock")
+ private boolean readLF(ProcessStats stats, AtomicFile file) {
try {
FileInputStream stream = file.openRead();
stats.read(stream);
@@ -387,7 +442,8 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return true;
}
- private ArrayList<String> getCommittedFiles(int minNum, boolean inclCurrent,
+ @GuardedBy("mFileLock")
+ private ArrayList<String> getCommittedFilesLF(int minNum, boolean inclCurrent,
boolean inclCheckedIn) {
File[] files = mBaseDir.listFiles();
if (files == null || files.length <= minNum) {
@@ -414,9 +470,9 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return filesArray;
}
- @GuardedBy("mAm")
- public void trimHistoricStatesWriteLocked() {
- ArrayList<String> filesArray = getCommittedFiles(MAX_HISTORIC_STATES, false, true);
+ @GuardedBy("mFileLock")
+ private void trimHistoricStatesWriteLF() {
+ ArrayList<String> filesArray = getCommittedFilesLF(MAX_HISTORIC_STATES, false, true);
if (filesArray == null) {
return;
}
@@ -427,8 +483,8 @@ public final class ProcessStatsService extends IProcessStats.Stub {
}
}
- @GuardedBy("mAm")
- boolean dumpFilteredProcessesCsvLocked(PrintWriter pw, String header,
+ @GuardedBy("mLock")
+ private boolean dumpFilteredProcessesCsvLocked(PrintWriter pw, String header,
boolean sepScreenStates, int[] screenStates, boolean sepMemStates, int[] memStates,
boolean sepProcStates, int[] procStates, long now, String reqPackage) {
ArrayList<ProcessState> procs = mProcessStats.collectProcessesLocked(
@@ -502,20 +558,21 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return res;
}
+ @Override
public byte[] getCurrentStats(List<ParcelFileDescriptor> historic) {
mAm.mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.PACKAGE_USAGE_STATS, null);
Parcel current = Parcel.obtain();
- synchronized (mAm) {
+ synchronized (mLock) {
long now = SystemClock.uptimeMillis();
mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
mProcessStats.mTimePeriodEndUptime = now;
mProcessStats.writeToParcel(current, now, 0);
}
- mWriteLock.lock();
+ mFileLock.lock();
try {
if (historic != null) {
- ArrayList<String> files = getCommittedFiles(0, false, true);
+ ArrayList<String> files = getCommittedFilesLF(0, false, true);
if (files != null) {
for (int i=files.size()-1; i>=0; i--) {
try {
@@ -529,7 +586,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
}
}
} finally {
- mWriteLock.unlock();
+ mFileLock.unlock();
}
return current.marshall();
}
@@ -563,9 +620,9 @@ public final class ProcessStatsService extends IProcessStats.Stub {
android.Manifest.permission.PACKAGE_USAGE_STATS, null);
long newHighWaterMark = highWaterMarkMs;
- mWriteLock.lock();
+ mFileLock.lock();
try {
- ArrayList<String> files = getCommittedFiles(0, false, true);
+ ArrayList<String> files = getCommittedFilesLF(0, false, true);
if (files != null) {
String highWaterMarkStr =
DateFormat.format("yyyy-MM-dd-HH-mm-ss", highWaterMarkMs).toString();
@@ -612,7 +669,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
} catch (IOException e) {
Slog.w(TAG, "Failure opening procstat file", e);
} finally {
- mWriteLock.unlock();
+ mFileLock.unlock();
}
return newHighWaterMark;
}
@@ -625,7 +682,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return mAm.mConstants.MIN_ASSOC_LOG_DURATION;
}
- private ParcelFileDescriptor protoToParcelFileDescriptor(ProcessStats stats, int section)
+ private static ParcelFileDescriptor protoToParcelFileDescriptor(ProcessStats stats, int section)
throws IOException {
final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
Thread thr = new Thread("ProcessStats pipe output") {
@@ -645,12 +702,13 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return fds[0];
}
+ @Override
public ParcelFileDescriptor getStatsOverTime(long minTime) {
mAm.mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.PACKAGE_USAGE_STATS, null);
Parcel current = Parcel.obtain();
long curTime;
- synchronized (mAm) {
+ synchronized (mLock) {
long now = SystemClock.uptimeMillis();
mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
mProcessStats.mTimePeriodEndUptime = now;
@@ -658,11 +716,11 @@ public final class ProcessStatsService extends IProcessStats.Stub {
curTime = mProcessStats.mTimePeriodEndRealtime
- mProcessStats.mTimePeriodStartRealtime;
}
- mWriteLock.lock();
+ mFileLock.lock();
try {
if (curTime < minTime) {
// Need to add in older stats to reach desired time.
- ArrayList<String> files = getCommittedFiles(0, false, true);
+ ArrayList<String> files = getCommittedFilesLF(0, false, true);
if (files != null && files.size() > 0) {
current.setDataPosition(0);
ProcessStats stats = ProcessStats.CREATOR.createFromParcel(current);
@@ -673,7 +731,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
AtomicFile file = new AtomicFile(new File(files.get(i)));
i--;
ProcessStats moreStats = new ProcessStats(false);
- readLocked(moreStats, file);
+ readLF(moreStats, file);
if (moreStats.mReadError == null) {
stats.add(moreStats);
StringBuilder sb = new StringBuilder();
@@ -712,13 +770,14 @@ public final class ProcessStatsService extends IProcessStats.Stub {
} catch (IOException e) {
Slog.w(TAG, "Failed building output pipe", e);
} finally {
- mWriteLock.unlock();
+ mFileLock.unlock();
}
return null;
}
+ @Override
public int getCurrentMemoryState() {
- synchronized (mAm) {
+ synchronized (mLock) {
return mLastMemOnlyState;
}
}
@@ -947,7 +1006,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
} else if ("--current".equals(arg)) {
currentOnly = true;
} else if ("--commit".equals(arg)) {
- synchronized (mAm) {
+ synchronized (mLock) {
mProcessStats.mFlags |= ProcessStats.FLAG_COMPLETE;
writeStateLocked(true, true);
pw.println("Process stats committed.");
@@ -962,29 +1021,39 @@ public final class ProcessStatsService extends IProcessStats.Stub {
}
section = parseSectionOptions(args[i]);
} else if ("--clear".equals(arg)) {
- synchronized (mAm) {
+ synchronized (mLock) {
mProcessStats.resetSafely();
- mAm.requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
- ArrayList<String> files = getCommittedFiles(0, true, true);
- if (files != null) {
- for (int fi=0; fi<files.size(); fi++) {
- (new File(files.get(fi))).delete();
+ scheduleRequestPssAllProcs(true, false);
+ mFileLock.lock();
+ try {
+ ArrayList<String> files = getCommittedFilesLF(0, true, true);
+ if (files != null) {
+ for (int fi = files.size() - 1; fi >= 0; fi--) {
+ (new File(files.get(fi))).delete();
+ }
}
+ } finally {
+ mFileLock.unlock();
}
pw.println("All process stats cleared.");
quit = true;
}
} else if ("--write".equals(arg)) {
- synchronized (mAm) {
+ synchronized (mLock) {
writeStateSyncLocked();
pw.println("Process stats written.");
quit = true;
}
} else if ("--read".equals(arg)) {
- synchronized (mAm) {
- readLocked(mProcessStats, mFile);
- pw.println("Process stats read.");
- quit = true;
+ synchronized (mLock) {
+ mFileLock.lock();
+ try {
+ readLF(mProcessStats, mFile);
+ pw.println("Process stats read.");
+ quit = true;
+ } finally {
+ mFileLock.unlock();
+ }
}
} else if ("--start-testing".equals(arg)) {
synchronized (mAm) {
@@ -999,17 +1068,17 @@ public final class ProcessStatsService extends IProcessStats.Stub {
quit = true;
}
} else if ("--pretend-screen-on".equals(arg)) {
- synchronized (mAm) {
+ synchronized (mLock) {
mInjectedScreenState = true;
}
quit = true;
} else if ("--pretend-screen-off".equals(arg)) {
- synchronized (mAm) {
+ synchronized (mLock) {
mInjectedScreenState = false;
}
quit = true;
} else if ("--stop-pretend-screen".equals(arg)) {
- synchronized (mAm) {
+ synchronized (mLock) {
mInjectedScreenState = null;
}
quit = true;
@@ -1060,7 +1129,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
}
}
pw.println();
- synchronized (mAm) {
+ synchronized (mLock) {
dumpFilteredProcessesCsvLocked(pw, null,
csvSepScreenStats, csvScreenStats, csvSepMemStats, csvMemStats,
csvSepProcStats, csvProcStats, now, reqPackage);
@@ -1090,14 +1159,26 @@ public final class ProcessStatsService extends IProcessStats.Stub {
return;
} else if (lastIndex > 0) {
pw.print("LAST STATS AT INDEX "); pw.print(lastIndex); pw.println(":");
- ArrayList<String> files = getCommittedFiles(0, false, true);
- if (lastIndex >= files.size()) {
- pw.print("Only have "); pw.print(files.size()); pw.println(" data sets");
- return;
+
+ ArrayList<String> files;
+ AtomicFile file;
+ ProcessStats processStats;
+
+ mFileLock.lock();
+ try {
+ files = getCommittedFilesLF(0, false, true);
+ if (lastIndex >= files.size()) {
+ pw.print("Only have "); pw.print(files.size()); pw.println(" data sets");
+ return;
+ }
+ file = new AtomicFile(new File(files.get(lastIndex)));
+ processStats = new ProcessStats(false);
+ readLF(processStats, file);
+ } finally {
+ mFileLock.unlock();
}
- AtomicFile file = new AtomicFile(new File(files.get(lastIndex)));
- ProcessStats processStats = new ProcessStats(false);
- readLocked(processStats, file);
+
+ // No lock is needed now, since only us have the access to the 'processStats'.
if (processStats.mReadError != null) {
if (isCheckin || isCompact) pw.print("err,");
pw.print("Failure reading "); pw.print(files.get(lastIndex));
@@ -1118,7 +1199,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
processStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpDetails,
dumpAll, activeOnly, section);
if (dumpAll) {
- pw.print(" mFile="); pw.println(mFile.getBaseFile());
+ pw.print(" mFile="); pw.println(getCurrentFile());
}
} else {
processStats.dumpSummaryLocked(pw, reqPackage, now, activeOnly);
@@ -1129,9 +1210,9 @@ public final class ProcessStatsService extends IProcessStats.Stub {
boolean sepNeeded = false;
if ((dumpAll || isCheckin) && !currentOnly) {
- mWriteLock.lock();
+ mFileLock.lock();
try {
- ArrayList<String> files = getCommittedFiles(0, false, !isCheckin);
+ ArrayList<String> files = getCommittedFilesLF(0, false, !isCheckin);
if (files != null) {
int start = isCheckin ? 0 : (files.size() - maxNum);
if (start < 0) {
@@ -1142,7 +1223,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
try {
AtomicFile file = new AtomicFile(new File(files.get(i)));
ProcessStats processStats = new ProcessStats(false);
- readLocked(processStats, file);
+ readLF(processStats, file);
if (processStats.mReadError != null) {
if (isCheckin || isCompact) pw.print("err,");
pw.print("Failure reading "); pw.print(files.get(i));
@@ -1188,11 +1269,11 @@ public final class ProcessStatsService extends IProcessStats.Stub {
}
}
} finally {
- mWriteLock.unlock();
+ mFileLock.unlock();
}
}
if (!isCheckin) {
- synchronized (mAm) {
+ synchronized (mLock) {
if (isCompact) {
mProcessStats.dumpCheckinLocked(pw, reqPackage, section);
} else {
@@ -1204,7 +1285,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
mProcessStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpDetails,
dumpAll, activeOnly, section);
if (dumpAll) {
- pw.print(" mFile="); pw.println(mFile.getBaseFile());
+ pw.print(" mFile="); pw.println(getCurrentFile());
}
} else {
mProcessStats.dumpSummaryLocked(pw, reqPackage, now, activeOnly);
@@ -1249,7 +1330,7 @@ public final class ProcessStatsService extends IProcessStats.Stub {
// dump current procstats
long now;
- synchronized (mAm) {
+ synchronized (mLock) {
now = SystemClock.uptimeMillis();
final long token = proto.start(ProcessStatsServiceDumpProto.PROCSTATS_NOW);
mProcessStats.dumpDebug(proto, now, ProcessStats.REPORT_ALL);
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 022b04d89774..4a2703056871 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -528,8 +528,9 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
return tracker;
}
if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
- tracker = ams.mProcessStats.getServiceStateLocked(serviceInfo.packageName,
- serviceInfo.applicationInfo.uid, serviceInfo.applicationInfo.longVersionCode,
+ tracker = ams.mProcessStats.getServiceState(serviceInfo.packageName,
+ serviceInfo.applicationInfo.uid,
+ serviceInfo.applicationInfo.longVersionCode,
serviceInfo.processName, serviceInfo.name);
tracker.applyNewOwner(this);
}
@@ -546,7 +547,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
public void makeRestarting(int memFactor, long now) {
if (restartTracker == null) {
if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
- restartTracker = ams.mProcessStats.getServiceStateLocked(serviceInfo.packageName,
+ restartTracker = ams.mProcessStats.getServiceState(
+ serviceInfo.packageName,
serviceInfo.applicationInfo.uid,
serviceInfo.applicationInfo.longVersionCode,
serviceInfo.processName, serviceInfo.name);
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 2a267c413c31..1b2711d3938b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -99,6 +99,7 @@ import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
+import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
@@ -165,7 +166,7 @@ public class MockingOomAdjusterTests {
setFieldValue(ActivityManagerService.class, sService, "mHandler",
mock(ActivityManagerService.MainHandler.class));
setFieldValue(ActivityManagerService.class, sService, "mProcessStats",
- mock(ProcessStatsService.class));
+ new ProcessStatsService(sService, new File(sContext.getFilesDir(), "procstats")));
setFieldValue(ActivityManagerService.class, sService, "mBackupTargets",
mock(SparseArray.class));
setFieldValue(ActivityManagerService.class, sService, "mOomAdjProfiler",