Merge "Fix lock contention in ResourcesManager"

This commit is contained in:
Charles Chen
2020-08-25 01:26:30 +00:00
committed by Android (Google) Code Review
2 changed files with 40 additions and 19 deletions

View File

@@ -17,7 +17,6 @@ package android.app;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.view.Display;
@@ -136,4 +135,22 @@ public class ResourcesManagerPerfTest {
}
}
}
@Test
public void getDisplayMetrics() {
ResourcesManager resourcesManager = ResourcesManager.getInstance();
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
state.pauseTiming();
// Invalidate cache.
resourcesManager.applyConfigurationToResourcesLocked(
resourcesManager.getConfiguration(), null);
state.resumeTiming();
// Invoke twice for testing cache.
resourcesManager.getDisplayMetrics();
resourcesManager.getDisplayMetrics();
}
}
}

View File

@@ -54,6 +54,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
@@ -245,7 +246,7 @@ public class ResourcesManager {
/**
* A cache of DisplayId, DisplayAdjustments to Display.
*/
private final ArrayMap<Pair<Integer, DisplayAdjustments>, WeakReference<Display>>
private final ArrayMap<Pair<Integer, DisplayAdjustments>, SoftReference<Display>>
mAdjustedDisplays = new ArrayMap<>();
/**
@@ -373,25 +374,28 @@ public class ResourcesManager {
? new DisplayAdjustments(displayAdjustments) : new DisplayAdjustments();
final Pair<Integer, DisplayAdjustments> key =
Pair.create(displayId, displayAdjustmentsCopy);
SoftReference<Display> sd;
synchronized (this) {
WeakReference<Display> wd = mAdjustedDisplays.get(key);
if (wd != null) {
final Display display = wd.get();
if (display != null) {
return display;
}
}
final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
if (dm == null) {
// may be null early in system startup
return null;
}
final Display display = dm.getCompatibleDisplay(displayId, key.second);
if (display != null) {
mAdjustedDisplays.put(key, new WeakReference<>(display));
}
return display;
sd = mAdjustedDisplays.get(key);
}
if (sd != null) {
final Display display = sd.get();
if (display != null) {
return display;
}
}
final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
if (dm == null) {
// may be null early in system startup
return null;
}
final Display display = dm.getCompatibleDisplay(displayId, key.second);
if (display != null) {
synchronized (this) {
mAdjustedDisplays.put(key, new SoftReference<>(display));
}
}
return display;
}
/**