aboutsummaryrefslogtreecommitdiffstats
path: root/guava
diff options
context:
space:
mode:
authorPaul Duffin <paulduffin@google.com>2015-01-19 12:32:57 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2015-01-19 12:32:57 +0000
commit3c002e2a4b1fab207b8cd398935a2c881c15196b (patch)
tree512166948886f887d64cd2e59db59f0745c0a63d /guava
parent1e904aaa2b9789fe7c756ca18dc0dbb88ee1885f (diff)
parentca6be3b3bd5086563797b6703a2e94a34e379b4d (diff)
downloadandroid_external_guava-3c002e2a4b1fab207b8cd398935a2c881c15196b.tar.gz
android_external_guava-3c002e2a4b1fab207b8cd398935a2c881c15196b.tar.bz2
android_external_guava-3c002e2a4b1fab207b8cd398935a2c881c15196b.zip
am ca6be3b3: Merge "Revert "Replace usages of Unsafe.compareAndSwap(Int|Long)""
* commit 'ca6be3b3bd5086563797b6703a2e94a34e379b4d': Revert "Replace usages of Unsafe.compareAndSwap(Int|Long)"
Diffstat (limited to 'guava')
-rw-r--r--guava/src/com/google/common/cache/Striped64.java75
1 files changed, 64 insertions, 11 deletions
diff --git a/guava/src/com/google/common/cache/Striped64.java b/guava/src/com/google/common/cache/Striped64.java
index be2f64d..e045453 100644
--- a/guava/src/com/google/common/cache/Striped64.java
+++ b/guava/src/com/google/common/cache/Striped64.java
@@ -12,8 +12,6 @@
package com.google.common.cache;
import java.util.Random;
-import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
-import java.util.concurrent.atomic.AtomicLongFieldUpdater;
/**
* A package-local class holding common representation and mechanics
@@ -99,11 +97,23 @@ abstract class Striped64 extends Number {
Cell(long x) { value = x; }
final boolean cas(long cmp, long val) {
- return valueUpdater.compareAndSet(this, cmp, value);
+ return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val);
+ }
+
+ // Unsafe mechanics
+ private static final sun.misc.Unsafe UNSAFE;
+ private static final long valueOffset;
+ static {
+ try {
+ UNSAFE = getUnsafe();
+ Class<?> ak = Cell.class;
+ valueOffset = UNSAFE.objectFieldOffset
+ (ak.getDeclaredField("value"));
+ } catch (Exception e) {
+ throw new Error(e);
+ }
}
- private static final AtomicLongFieldUpdater<Cell> valueUpdater =
- AtomicLongFieldUpdater.newUpdater(Cell.class, "value");
}
/**
@@ -163,14 +173,14 @@ abstract class Striped64 extends Number {
* CASes the base field.
*/
final boolean casBase(long cmp, long val) {
- return baseUpdater.compareAndSet(this, cmp, val);
+ return UNSAFE.compareAndSwapLong(this, baseOffset, cmp, val);
}
/**
* CASes the busy field from 0 to 1 to acquire lock.
*/
final boolean casBusy() {
- return busyUpdater.compareAndSet(this, 0, 1);
+ return UNSAFE.compareAndSwapInt(this, busyOffset, 0, 1);
}
/**
@@ -287,8 +297,51 @@ abstract class Striped64 extends Number {
}
}
- private static final AtomicLongFieldUpdater<Striped64> baseUpdater =
- AtomicLongFieldUpdater.newUpdater(Striped64.class, "base");
- private static final AtomicIntegerFieldUpdater<Striped64> busyUpdater =
- AtomicIntegerFieldUpdater.newUpdater(Striped64.class, "busy");
+ // Unsafe mechanics
+ private static final sun.misc.Unsafe UNSAFE;
+ private static final long baseOffset;
+ private static final long busyOffset;
+ static {
+ try {
+ UNSAFE = getUnsafe();
+ Class<?> sk = Striped64.class;
+ baseOffset = UNSAFE.objectFieldOffset
+ (sk.getDeclaredField("base"));
+ busyOffset = UNSAFE.objectFieldOffset
+ (sk.getDeclaredField("busy"));
+ } catch (Exception e) {
+ throw new Error(e);
+ }
+ }
+
+ /**
+ * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package.
+ * Replace with a simple call to Unsafe.getUnsafe when integrating
+ * into a jdk.
+ *
+ * @return a sun.misc.Unsafe
+ */
+ private static sun.misc.Unsafe getUnsafe() {
+ try {
+ return sun.misc.Unsafe.getUnsafe();
+ } catch (SecurityException tryReflectionInstead) {}
+ try {
+ return java.security.AccessController.doPrivileged
+ (new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() {
+ public sun.misc.Unsafe run() throws Exception {
+ Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
+ for (java.lang.reflect.Field f : k.getDeclaredFields()) {
+ f.setAccessible(true);
+ Object x = f.get(null);
+ if (k.isInstance(x))
+ return k.cast(x);
+ }
+ throw new NoSuchFieldError("the Unsafe");
+ }});
+ } catch (java.security.PrivilegedActionException e) {
+ throw new RuntimeException("Could not initialize intrinsics",
+ e.getCause());
+ }
+ }
+
}