summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jeremy Meyer <jakmcbane@google.com> 2025-01-15 16:24:41 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2025-01-15 16:24:41 -0800
commitb1a14cd2048320ab18bf36bf89967f16f2f8f803 (patch)
tree2cb2c7f2960be469a7c513c4a735dc38df56b7a0
parentfffd3d56cc32de929259faa92765b605447c1033 (diff)
parente26dbf682771487f981bf801a31dccb18d43f1c5 (diff)
Merge "Reduce lock contention in AssetManager.java" into main
-rw-r--r--core/java/android/content/res/AssetManager.java55
1 files changed, 28 insertions, 27 deletions
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index bbfae8117b16..7cd2d31ac974 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -62,6 +62,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* Provides access to an application's raw asset files; see {@link Resources}
@@ -133,7 +134,7 @@ public final class AssetManager implements AutoCloseable {
// Debug/reference counting implementation.
@GuardedBy("this") private boolean mOpen = true;
- @GuardedBy("this") private int mNumRefs = 1;
+ private AtomicInteger mNumRefs = new AtomicInteger(1);
@GuardedBy("this") private HashMap<Long, RuntimeException> mRefStacks;
private ResourcesLoader[] mLoaders;
@@ -244,7 +245,7 @@ public final class AssetManager implements AutoCloseable {
mObject = nativeCreate();
if (DEBUG_REFS) {
- mNumRefs = 0;
+ mNumRefs.set(0);
incRefsLocked(hashCode());
}
@@ -260,7 +261,7 @@ public final class AssetManager implements AutoCloseable {
private AssetManager(boolean sentinel) {
mObject = nativeCreate();
if (DEBUG_REFS) {
- mNumRefs = 0;
+ mNumRefs.set(0);
incRefsLocked(hashCode());
}
}
@@ -324,7 +325,7 @@ public final class AssetManager implements AutoCloseable {
}
mOpen = false;
- decRefsLocked(hashCode());
+ decRefs(hashCode());
}
}
@@ -1235,9 +1236,7 @@ public final class AssetManager implements AutoCloseable {
}
void xmlBlockGone(int id) {
- synchronized (this) {
- decRefsLocked(id);
- }
+ decRefs(id);
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -1308,9 +1307,7 @@ public final class AssetManager implements AutoCloseable {
}
void releaseTheme(long themePtr) {
- synchronized (this) {
- decRefsLocked(themePtr);
- }
+ decRefs(themePtr);
}
static long getThemeFreeFunction() {
@@ -1332,7 +1329,7 @@ public final class AssetManager implements AutoCloseable {
if (this != newAssetManager) {
synchronized (this) {
ensureValidLocked();
- decRefsLocked(themePtr);
+ decRefs(themePtr);
}
synchronized (newAssetManager) {
newAssetManager.ensureValidLocked();
@@ -1364,8 +1361,8 @@ public final class AssetManager implements AutoCloseable {
@Override
protected void finalize() throws Throwable {
- if (DEBUG_REFS && mNumRefs != 0) {
- Log.w(TAG, "AssetManager " + this + " finalized with non-zero refs: " + mNumRefs);
+ if (DEBUG_REFS && mNumRefs.get() != 0) {
+ Log.w(TAG, "AssetManager " + this + " finalized with non-zero refs: " + mNumRefs.get());
if (mRefStacks != null) {
for (RuntimeException e : mRefStacks.values()) {
Log.w(TAG, "Reference from here", e);
@@ -1473,9 +1470,7 @@ public final class AssetManager implements AutoCloseable {
nativeAssetDestroy(mAssetNativePtr);
mAssetNativePtr = 0;
- synchronized (AssetManager.this) {
- decRefsLocked(hashCode());
- }
+ decRefs(hashCode());
}
}
@@ -1680,19 +1675,25 @@ public final class AssetManager implements AutoCloseable {
RuntimeException ex = new RuntimeException();
mRefStacks.put(id, ex);
}
- mNumRefs++;
+ mNumRefs.incrementAndGet();
}
- @GuardedBy("this")
- private void decRefsLocked(long id) {
- if (DEBUG_REFS && mRefStacks != null) {
- mRefStacks.remove(id);
- }
- mNumRefs--;
- if (mNumRefs == 0 && mObject != 0) {
- nativeDestroy(mObject);
- mObject = 0;
- mApkAssets = sEmptyApkAssets;
+ private void decRefs(long id) {
+ if (DEBUG_REFS) {
+ synchronized (this) {
+ if (mRefStacks != null) {
+ mRefStacks.remove(id);
+ }
+ }
+ }
+ if (mNumRefs.decrementAndGet() == 0) {
+ synchronized (this) {
+ if (mNumRefs.get() == 0 && mObject != 0) {
+ nativeDestroy(mObject);
+ mObject = 0;
+ mApkAssets = sEmptyApkAssets;
+ }
+ }
}
}