Avoid deadlock between ActivityManagerService and ProcessStatsService.

Root Cause:
Case 1
getStatsOverTime(#483) // lock mWriteLock, wait AMS
async performWriteState(#269) // lock mPendingWriteLock, wait mWriteLock
writeStateLocked(#218) // lock AMS, wait mPendingWriteLock

Case 2
getStatsOverTime(#483) // lock mWriteLock, wait AMS
writeStateSyncLocked,writeStateLocked(#269) // lock AMS, wait mWriteLock

Solution:
Reduce nested lock.

Others also post the same solution:
I437a5cedceb34292a6bd1d9e7610f52b1478e424

Change-Id: Ie9395f3f6359fe59e2282674fcfec9d123e53f25
This commit is contained in:
riddle_hsu
2014-11-15 18:40:08 +08:00
parent 5e6cf24213
commit 61231a5eff

View File

@@ -445,14 +445,14 @@ public final class ProcessStatsService extends IProcessStats.Stub {
mAm.mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.PACKAGE_USAGE_STATS, null);
Parcel current = Parcel.obtain();
synchronized (mAm) {
long now = SystemClock.uptimeMillis();
mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
mProcessStats.mTimePeriodEndUptime = now;
mProcessStats.writeToParcel(current, now, 0);
}
mWriteLock.lock();
try {
synchronized (mAm) {
long now = SystemClock.uptimeMillis();
mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
mProcessStats.mTimePeriodEndUptime = now;
mProcessStats.writeToParcel(current, now, 0);
}
if (historic != null) {
ArrayList<String> files = getCommittedFiles(0, false, true);
if (files != null) {
@@ -476,18 +476,18 @@ public final class ProcessStatsService extends IProcessStats.Stub {
public ParcelFileDescriptor getStatsOverTime(long minTime) {
mAm.mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.PACKAGE_USAGE_STATS, null);
Parcel current = Parcel.obtain();
long curTime;
synchronized (mAm) {
long now = SystemClock.uptimeMillis();
mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
mProcessStats.mTimePeriodEndUptime = now;
mProcessStats.writeToParcel(current, now, 0);
curTime = mProcessStats.mTimePeriodEndRealtime
- mProcessStats.mTimePeriodStartRealtime;
}
mWriteLock.lock();
try {
Parcel current = Parcel.obtain();
long curTime;
synchronized (mAm) {
long now = SystemClock.uptimeMillis();
mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
mProcessStats.mTimePeriodEndUptime = now;
mProcessStats.writeToParcel(current, now, 0);
curTime = mProcessStats.mTimePeriodEndRealtime
- mProcessStats.mTimePeriodStartRealtime;
}
if (curTime < minTime) {
// Need to add in older stats to reach desired time.
ArrayList<String> files = getCommittedFiles(0, false, true);