Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
java.util.concurrent.atomic/Atomic*.getAndIncrement() and getAndAdd() are currently implemented as CAS loops. On x86/x64, these could be intrinsified into lock:xadd. The latter is far less heavy-weight than cmpxchg. After discussions with Doug Lea and Dave Dice, we should extend Unsafe a bit to provide intrinsifiable operations to take advantage of xadd and xchg. Here's the rough interface addition. These are slightly different than normal Unsafe since they start with Java implementations which are always valid. They can be replaced with intrinsics if the platform provides a fast implementation. /** * Atomically update Java variable by <tt>delta</tt> returning * the previous value. * @return the previous value */ public int getAndAddInt(Object o, long offset, int delta) { for (;;) { int current = getInt(o, offset); int next = current + delta; if (compareAndSwapInt(o, offset, current, next)) { return current; } } } /** * Atomically update Java variable by <tt>delta</tt> returning * the previous value. * @return the previous value */ public long getAndAddLong(Object o, long offset, long delta) { for (;;) { long current = getLongVolatile(o, offset); long next = current + delta; if (compareAndSwapLong(o, offset, current, next)) { return current; } } } /** * Atomically sets the field of the given object at the given offset * to the given value and returns the old value. * * @param o An object whose field to get and set * @param newValue the new value * @return the previous value */ public int getAndSet(Object o, long offset, int newValue) { for (;;) { int current = getInt(o, offset); if (compareAndSwapInt(o, offset, current, newValue)) { return current; } } } /** * Atomically sets the field of the given object at the given offset * to the given value and returns the old value. * * @param o An object whose field to get and set * @param newValue the new value * @return the previous value */ public long getAndSet(Object o, long offset, long newValue) { for (;;) { long current = getLongVolatile(o, offset); if (compareAndSwapLong(o, offset, current, newValue)) { return current; } } } /** * Atomically sets the field of the given object at the given offset * to the given value and returns the old value. * * @param o An object whose field to get and set * @param newValue the new value * @return the previous value */ public Object getAndSet(Object o, long offset, Object newValue) { for (;;) { Object current = getObject(o, offset); if (compareAndSwapObject(o, offset, current, newValue)) { return current; } } }
|