diff options
author | Paul Duffin <paulduffin@google.com> | 2015-01-19 12:32:57 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-01-19 12:32:57 +0000 |
commit | 3c002e2a4b1fab207b8cd398935a2c881c15196b (patch) | |
tree | 512166948886f887d64cd2e59db59f0745c0a63d /guava | |
parent | 1e904aaa2b9789fe7c756ca18dc0dbb88ee1885f (diff) | |
parent | ca6be3b3bd5086563797b6703a2e94a34e379b4d (diff) | |
download | android_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.java | 75 |
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()); + } + } + } |