17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* 26 * This file is available under and governed by the GNU General Public 27 * License version 2 only, as published by the Free Software Foundation. 28 * However, the following notice accompanied the original version of this 29 * file: 30 * 31 * Written by Doug Lea with assistance from members of JCP JSR-166 32 * Expert Group and released to the public domain, as explained at 33 * http://creativecommons.org/publicdomain/zero/1.0/ 34 */ 35 36 package java.util.concurrent.atomic; 37 import sun.misc.Unsafe; 38 import java.lang.reflect.Field; 39 import java.lang.reflect.Modifier; 40 import java.security.AccessController; 41 import java.security.PrivilegedExceptionAction; 42 import java.security.PrivilegedActionException; 43 44 /** 45 * A reflection-based utility that enables atomic updates to 46 * designated {@code volatile int} fields of designated classes. 47 * This class is designed for use in atomic data structures in which 48 * several fields of the same node are independently subject to atomic 49 * updates. 50 * 51 * <p>Note that the guarantees of the {@code compareAndSet} 52 * method in this class are weaker than in other atomic classes. 53 * Because this class cannot ensure that all uses of the field 54 * are appropriate for purposes of atomic access, it can 55 * guarantee atomicity only with respect to other invocations of 56 * {@code compareAndSet} and {@code set} on the same updater. 245 next = prev - 1; 246 } while (!compareAndSet(obj, prev, next)); 247 return next; 248 } 249 250 /** 251 * Atomically adds the given value to the current value of the field of 252 * the given object managed by this updater. 253 * 254 * @param obj An object whose field to get and set 255 * @param delta the value to add 256 * @return the updated value 257 */ 258 public int addAndGet(T obj, int delta) { 259 int prev, next; 260 do { 261 prev = get(obj); 262 next = prev + delta; 263 } while (!compareAndSet(obj, prev, next)); 264 return next; 265 } 266 267 /** 268 * Standard hotspot implementation using intrinsics 269 */ 270 private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<T> { 271 private static final Unsafe unsafe = Unsafe.getUnsafe(); 272 private final long offset; 273 private final Class<T> tclass; 274 private final Class<?> cclass; 275 276 AtomicIntegerFieldUpdaterImpl(final Class<T> tclass, final String fieldName) { 277 final Field field; 278 final Class<?> caller; 279 final int modifiers; 280 try { 281 field = AccessController.doPrivileged( 282 new PrivilegedExceptionAction<Field>() { 283 public Field run() throws NoSuchFieldException { 284 return tclass.getDeclaredField(fieldName); | 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* 26 * This file is available under and governed by the GNU General Public 27 * License version 2 only, as published by the Free Software Foundation. 28 * However, the following notice accompanied the original version of this 29 * file: 30 * 31 * Written by Doug Lea with assistance from members of JCP JSR-166 32 * Expert Group and released to the public domain, as explained at 33 * http://creativecommons.org/publicdomain/zero/1.0/ 34 */ 35 36 package java.util.concurrent.atomic; 37 import java.util.function.IntUnaryOperator; 38 import java.util.function.IntBinaryOperator; 39 import sun.misc.Unsafe; 40 import java.lang.reflect.Field; 41 import java.lang.reflect.Modifier; 42 import java.security.AccessController; 43 import java.security.PrivilegedExceptionAction; 44 import java.security.PrivilegedActionException; 45 46 /** 47 * A reflection-based utility that enables atomic updates to 48 * designated {@code volatile int} fields of designated classes. 49 * This class is designed for use in atomic data structures in which 50 * several fields of the same node are independently subject to atomic 51 * updates. 52 * 53 * <p>Note that the guarantees of the {@code compareAndSet} 54 * method in this class are weaker than in other atomic classes. 55 * Because this class cannot ensure that all uses of the field 56 * are appropriate for purposes of atomic access, it can 57 * guarantee atomicity only with respect to other invocations of 58 * {@code compareAndSet} and {@code set} on the same updater. 247 next = prev - 1; 248 } while (!compareAndSet(obj, prev, next)); 249 return next; 250 } 251 252 /** 253 * Atomically adds the given value to the current value of the field of 254 * the given object managed by this updater. 255 * 256 * @param obj An object whose field to get and set 257 * @param delta the value to add 258 * @return the updated value 259 */ 260 public int addAndGet(T obj, int delta) { 261 int prev, next; 262 do { 263 prev = get(obj); 264 next = prev + delta; 265 } while (!compareAndSet(obj, prev, next)); 266 return next; 267 } 268 269 /** 270 * Atomically updates the current value with the results of 271 * applying the given function. The function should be 272 * side-effect-free, since it may be re-applied when attempted 273 * updates fail due to contention among threads. 274 * 275 * @param obj An object whose field to get and set 276 * @param updateFunction a side-effect-free function 277 * @return the previous value 278 * @since 1.8 279 */ 280 public final int getAndUpdate(T obj, IntUnaryOperator updateFunction) { 281 int prev, next; 282 do { 283 prev = get(obj); 284 next = updateFunction.operateAsInt(prev); 285 } while (!compareAndSet(obj, prev, next)); 286 return prev; 287 } 288 289 /** 290 * Atomically updates the current value with the results of 291 * applying the given function. The function should be 292 * side-effect-free, since it may be re-applied when attempted 293 * updates fail due to contention among threads. 294 * 295 * @param obj An object whose field to get and set 296 * @param updateFunction a side-effect-free function 297 * @return the updated value 298 * @since 1.8 299 */ 300 public final int updateAndGet(T obj, IntUnaryOperator updateFunction) { 301 int prev, next; 302 do { 303 prev = get(obj); 304 next = updateFunction.operateAsInt(prev); 305 } while (!compareAndSet(obj, prev, next)); 306 return next; 307 } 308 309 /** 310 * Atomically updates the current value with the results of 311 * applying the given function to the current and given values. 312 * The function should be side-effect-free, since it may be 313 * re-applied when attempted updates fail due to contention among 314 * threads. The function is applied with the current value as its 315 * first argument, and the given update as the second argument. 316 * 317 * @param obj An object whose field to get and set 318 * @param x the update value 319 * @param accumulatorFunction a side-effect-free function of two arguments 320 * @return the previous value 321 * @since 1.8 322 */ 323 public final int getAndAccumulate(T obj, int x, 324 IntBinaryOperator accumulatorFunction) { 325 int prev, next; 326 do { 327 prev = get(obj); 328 next = accumulatorFunction.operateAsInt(prev, x); 329 } while (!compareAndSet(obj, prev, next)); 330 return prev; 331 } 332 333 /** 334 * Atomically updates the current value with the results of 335 * applying the given function to the current and given values. 336 * The function should be side-effect-free, since it may be 337 * re-applied when attempted updates fail due to contention among 338 * threads. The function is applied with the current value as its 339 * first argument, and the given update as the second argument. 340 * 341 * @param obj An object whose field to get and set 342 * @param x the update value 343 * @param accumulatorFunction a side-effect-free function of two arguments 344 * @return the updated value 345 * @since 1.8 346 */ 347 public final int accumulateAndGet(T obj, int x, 348 IntBinaryOperator accumulatorFunction) { 349 int prev, next; 350 do { 351 prev = get(obj); 352 next = accumulatorFunction.operateAsInt(prev, x); 353 } while (!compareAndSet(obj, prev, next)); 354 return next; 355 } 356 357 /** 358 * Standard hotspot implementation using intrinsics 359 */ 360 private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<T> { 361 private static final Unsafe unsafe = Unsafe.getUnsafe(); 362 private final long offset; 363 private final Class<T> tclass; 364 private final Class<?> cclass; 365 366 AtomicIntegerFieldUpdaterImpl(final Class<T> tclass, final String fieldName) { 367 final Field field; 368 final Class<?> caller; 369 final int modifiers; 370 try { 371 field = AccessController.doPrivileged( 372 new PrivilegedExceptionAction<Field>() { 373 public Field run() throws NoSuchFieldException { 374 return tclass.getDeclaredField(fieldName); |