1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 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 38 import dalvik.system.VMStack; // Android-added 39 import java.lang.reflect.Field; 40 import java.lang.reflect.Modifier; 41 import java.security.AccessController; 42 import java.security.PrivilegedActionException; 43 import java.security.PrivilegedExceptionAction; 44 import java.util.function.LongBinaryOperator; 45 import java.util.function.LongUnaryOperator; 46 import sun.reflect.CallerSensitive; 47 import sun.reflect.Reflection; 48 49 /** 50 * A reflection-based utility that enables atomic updates to 51 * designated {@code volatile long} fields of designated classes. 52 * This class is designed for use in atomic data structures in which 53 * several fields of the same node are independently subject to atomic 54 * updates. 55 * 56 * <p>Note that the guarantees of the {@code compareAndSet} 57 * method in this class are weaker than in other atomic classes. 58 * Because this class cannot ensure that all uses of the field 59 * are appropriate for purposes of atomic access, it can 60 * guarantee atomicity only with respect to other invocations of 61 * {@code compareAndSet} and {@code set} on the same updater. 62 * 63 * @since 1.5 64 * @author Doug Lea 65 * @param <T> The type of the object holding the updatable field 66 */ 67 public abstract class AtomicLongFieldUpdater<T> { 68 /** 69 * Creates and returns an updater for objects with the given field. 70 * The Class argument is needed to check that reflective types and 71 * generic types match. 72 * 73 * @param tclass the class of the objects holding the field 74 * @param fieldName the name of the field to be updated 75 * @param <U> the type of instances of tclass 76 * @return the updater 77 * @throws IllegalArgumentException if the field is not a 78 * volatile long type 79 * @throws RuntimeException with a nested reflection-based 80 * exception if the class does not hold field or is the wrong type, 81 * or the field is inaccessible to the caller according to Java language 82 * access control 83 */ 84 @CallerSensitive newUpdater(Class<U> tclass, String fieldName)85 public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, 86 String fieldName) { 87 Class<?> caller = VMStack.getStackClass1(); // Android-changed 88 if (AtomicLong.VM_SUPPORTS_LONG_CAS) 89 return new CASUpdater<U>(tclass, fieldName, caller); 90 else 91 return new LockedUpdater<U>(tclass, fieldName, caller); 92 } 93 94 /** 95 * Protected do-nothing constructor for use by subclasses. 96 */ AtomicLongFieldUpdater()97 protected AtomicLongFieldUpdater() { 98 } 99 100 /** 101 * Atomically sets the field of the given object managed by this updater 102 * to the given updated value if the current value {@code ==} the 103 * expected value. This method is guaranteed to be atomic with respect to 104 * other calls to {@code compareAndSet} and {@code set}, but not 105 * necessarily with respect to other changes in the field. 106 * 107 * @param obj An object whose field to conditionally set 108 * @param expect the expected value 109 * @param update the new value 110 * @return {@code true} if successful 111 * @throws ClassCastException if {@code obj} is not an instance 112 * of the class possessing the field established in the constructor 113 */ compareAndSet(T obj, long expect, long update)114 public abstract boolean compareAndSet(T obj, long expect, long update); 115 116 /** 117 * Atomically sets the field of the given object managed by this updater 118 * to the given updated value if the current value {@code ==} the 119 * expected value. This method is guaranteed to be atomic with respect to 120 * other calls to {@code compareAndSet} and {@code set}, but not 121 * necessarily with respect to other changes in the field. 122 * 123 * <p><a href="package-summary.html#weakCompareAndSet">May fail 124 * spuriously and does not provide ordering guarantees</a>, so is 125 * only rarely an appropriate alternative to {@code compareAndSet}. 126 * 127 * @param obj An object whose field to conditionally set 128 * @param expect the expected value 129 * @param update the new value 130 * @return {@code true} if successful 131 * @throws ClassCastException if {@code obj} is not an instance 132 * of the class possessing the field established in the constructor 133 */ weakCompareAndSet(T obj, long expect, long update)134 public abstract boolean weakCompareAndSet(T obj, long expect, long update); 135 136 /** 137 * Sets the field of the given object managed by this updater to the 138 * given updated value. This operation is guaranteed to act as a volatile 139 * store with respect to subsequent invocations of {@code compareAndSet}. 140 * 141 * @param obj An object whose field to set 142 * @param newValue the new value 143 */ set(T obj, long newValue)144 public abstract void set(T obj, long newValue); 145 146 /** 147 * Eventually sets the field of the given object managed by this 148 * updater to the given updated value. 149 * 150 * @param obj An object whose field to set 151 * @param newValue the new value 152 * @since 1.6 153 */ lazySet(T obj, long newValue)154 public abstract void lazySet(T obj, long newValue); 155 156 /** 157 * Gets the current value held in the field of the given object managed 158 * by this updater. 159 * 160 * @param obj An object whose field to get 161 * @return the current value 162 */ get(T obj)163 public abstract long get(T obj); 164 165 /** 166 * Atomically sets the field of the given object managed by this updater 167 * to the given value and returns the old value. 168 * 169 * @param obj An object whose field to get and set 170 * @param newValue the new value 171 * @return the previous value 172 */ getAndSet(T obj, long newValue)173 public long getAndSet(T obj, long newValue) { 174 long prev; 175 do { 176 prev = get(obj); 177 } while (!compareAndSet(obj, prev, newValue)); 178 return prev; 179 } 180 181 /** 182 * Atomically increments by one the current value of the field of the 183 * given object managed by this updater. 184 * 185 * @param obj An object whose field to get and set 186 * @return the previous value 187 */ getAndIncrement(T obj)188 public long getAndIncrement(T obj) { 189 long prev, next; 190 do { 191 prev = get(obj); 192 next = prev + 1; 193 } while (!compareAndSet(obj, prev, next)); 194 return prev; 195 } 196 197 /** 198 * Atomically decrements by one the current value of the field of the 199 * given object managed by this updater. 200 * 201 * @param obj An object whose field to get and set 202 * @return the previous value 203 */ getAndDecrement(T obj)204 public long getAndDecrement(T obj) { 205 long prev, next; 206 do { 207 prev = get(obj); 208 next = prev - 1; 209 } while (!compareAndSet(obj, prev, next)); 210 return prev; 211 } 212 213 /** 214 * Atomically adds the given value to the current value of the field of 215 * the given object managed by this updater. 216 * 217 * @param obj An object whose field to get and set 218 * @param delta the value to add 219 * @return the previous value 220 */ getAndAdd(T obj, long delta)221 public long getAndAdd(T obj, long delta) { 222 long prev, next; 223 do { 224 prev = get(obj); 225 next = prev + delta; 226 } while (!compareAndSet(obj, prev, next)); 227 return prev; 228 } 229 230 /** 231 * Atomically increments by one the current value of the field of the 232 * given object managed by this updater. 233 * 234 * @param obj An object whose field to get and set 235 * @return the updated value 236 */ incrementAndGet(T obj)237 public long incrementAndGet(T obj) { 238 long prev, next; 239 do { 240 prev = get(obj); 241 next = prev + 1; 242 } while (!compareAndSet(obj, prev, next)); 243 return next; 244 } 245 246 /** 247 * Atomically decrements by one the current value of the field of the 248 * given object managed by this updater. 249 * 250 * @param obj An object whose field to get and set 251 * @return the updated value 252 */ decrementAndGet(T obj)253 public long decrementAndGet(T obj) { 254 long prev, next; 255 do { 256 prev = get(obj); 257 next = prev - 1; 258 } while (!compareAndSet(obj, prev, next)); 259 return next; 260 } 261 262 /** 263 * Atomically adds the given value to the current value of the field of 264 * the given object managed by this updater. 265 * 266 * @param obj An object whose field to get and set 267 * @param delta the value to add 268 * @return the updated value 269 */ addAndGet(T obj, long delta)270 public long addAndGet(T obj, long delta) { 271 long prev, next; 272 do { 273 prev = get(obj); 274 next = prev + delta; 275 } while (!compareAndSet(obj, prev, next)); 276 return next; 277 } 278 279 /** 280 * Atomically updates the field of the given object managed by this updater 281 * with the results of applying the given function, returning the previous 282 * value. The function should be side-effect-free, since it may be 283 * re-applied when attempted updates fail due to contention among threads. 284 * 285 * @param obj An object whose field to get and set 286 * @param updateFunction a side-effect-free function 287 * @return the previous value 288 * @since 1.8 289 */ getAndUpdate(T obj, LongUnaryOperator updateFunction)290 public final long getAndUpdate(T obj, LongUnaryOperator updateFunction) { 291 long prev, next; 292 do { 293 prev = get(obj); 294 next = updateFunction.applyAsLong(prev); 295 } while (!compareAndSet(obj, prev, next)); 296 return prev; 297 } 298 299 /** 300 * Atomically updates the field of the given object managed by this updater 301 * with the results of applying the given function, returning the updated 302 * value. The function should be side-effect-free, since it may be 303 * re-applied when attempted updates fail due to contention among threads. 304 * 305 * @param obj An object whose field to get and set 306 * @param updateFunction a side-effect-free function 307 * @return the updated value 308 * @since 1.8 309 */ updateAndGet(T obj, LongUnaryOperator updateFunction)310 public final long updateAndGet(T obj, LongUnaryOperator updateFunction) { 311 long prev, next; 312 do { 313 prev = get(obj); 314 next = updateFunction.applyAsLong(prev); 315 } while (!compareAndSet(obj, prev, next)); 316 return next; 317 } 318 319 /** 320 * Atomically updates the field of the given object managed by this 321 * updater with the results of applying the given function to the 322 * current and given values, returning the previous value. The 323 * function should be side-effect-free, since it may be re-applied 324 * when attempted updates fail due to contention among threads. The 325 * function is applied with the current value as its first argument, 326 * and the given update as the second argument. 327 * 328 * @param obj An object whose field to get and set 329 * @param x the update value 330 * @param accumulatorFunction a side-effect-free function of two arguments 331 * @return the previous value 332 * @since 1.8 333 */ getAndAccumulate(T obj, long x, LongBinaryOperator accumulatorFunction)334 public final long getAndAccumulate(T obj, long x, 335 LongBinaryOperator accumulatorFunction) { 336 long prev, next; 337 do { 338 prev = get(obj); 339 next = accumulatorFunction.applyAsLong(prev, x); 340 } while (!compareAndSet(obj, prev, next)); 341 return prev; 342 } 343 344 /** 345 * Atomically updates the field of the given object managed by this 346 * updater with the results of applying the given function to the 347 * current and given values, returning the updated value. The 348 * function should be side-effect-free, since it may be re-applied 349 * when attempted updates fail due to contention among threads. The 350 * function is applied with the current value as its first argument, 351 * and the given update as the second argument. 352 * 353 * @param obj An object whose field to get and set 354 * @param x the update value 355 * @param accumulatorFunction a side-effect-free function of two arguments 356 * @return the updated value 357 * @since 1.8 358 */ accumulateAndGet(T obj, long x, LongBinaryOperator accumulatorFunction)359 public final long accumulateAndGet(T obj, long x, 360 LongBinaryOperator accumulatorFunction) { 361 long prev, next; 362 do { 363 prev = get(obj); 364 next = accumulatorFunction.applyAsLong(prev, x); 365 } while (!compareAndSet(obj, prev, next)); 366 return next; 367 } 368 369 private static final class CASUpdater<T> extends AtomicLongFieldUpdater<T> { 370 private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); 371 private final long offset; 372 /** 373 * if field is protected, the subclass constructing updater, else 374 * the same as tclass 375 */ 376 private final Class<?> cclass; 377 /** class holding the field */ 378 private final Class<T> tclass; 379 CASUpdater(final Class<T> tclass, final String fieldName, final Class<?> caller)380 CASUpdater(final Class<T> tclass, final String fieldName, 381 final Class<?> caller) { 382 final Field field; 383 final int modifiers; 384 try { 385 field = tclass.getDeclaredField(fieldName); // Android-changed 386 modifiers = field.getModifiers(); 387 // BEGIN Android-removed 388 // sun.reflect.misc.ReflectUtil.ensureMemberAccess( 389 // caller, tclass, null, modifiers); 390 // ClassLoader cl = tclass.getClassLoader(); 391 // ClassLoader ccl = caller.getClassLoader(); 392 // if ((ccl != null) && (ccl != cl) && 393 // ((cl == null) || !isAncestor(cl, ccl))) { 394 // sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); 395 // } 396 // END Android-removed 397 // BEGIN Android-removed 398 // } catch (PrivilegedActionException pae) { 399 // throw new RuntimeException(pae.getException()); 400 // END Android-removed 401 } catch (Exception ex) { 402 throw new RuntimeException(ex); 403 } 404 405 if (field.getType() != long.class) 406 throw new IllegalArgumentException("Must be long type"); 407 408 if (!Modifier.isVolatile(modifiers)) 409 throw new IllegalArgumentException("Must be volatile type"); 410 411 this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass; 412 this.tclass = tclass; 413 this.offset = U.objectFieldOffset(field); 414 } 415 416 /** 417 * Checks that target argument is instance of cclass. On 418 * failure, throws cause. 419 */ accessCheck(T obj)420 private final void accessCheck(T obj) { 421 if (!cclass.isInstance(obj)) 422 throwAccessCheckException(obj); 423 } 424 425 /** 426 * Throws access exception if accessCheck failed due to 427 * protected access, else ClassCastException. 428 */ throwAccessCheckException(T obj)429 private final void throwAccessCheckException(T obj) { 430 if (cclass == tclass) 431 throw new ClassCastException(); 432 else 433 throw new RuntimeException( 434 new IllegalAccessException( 435 "Class " + 436 cclass.getName() + 437 " can not access a protected member of class " + 438 tclass.getName() + 439 " using an instance of " + 440 obj.getClass().getName())); 441 } 442 compareAndSet(T obj, long expect, long update)443 public final boolean compareAndSet(T obj, long expect, long update) { 444 accessCheck(obj); 445 return U.compareAndSwapLong(obj, offset, expect, update); 446 } 447 weakCompareAndSet(T obj, long expect, long update)448 public final boolean weakCompareAndSet(T obj, long expect, long update) { 449 accessCheck(obj); 450 return U.compareAndSwapLong(obj, offset, expect, update); 451 } 452 set(T obj, long newValue)453 public final void set(T obj, long newValue) { 454 accessCheck(obj); 455 U.putLongVolatile(obj, offset, newValue); 456 } 457 lazySet(T obj, long newValue)458 public final void lazySet(T obj, long newValue) { 459 accessCheck(obj); 460 U.putOrderedLong(obj, offset, newValue); 461 } 462 get(T obj)463 public final long get(T obj) { 464 accessCheck(obj); 465 return U.getLongVolatile(obj, offset); 466 } 467 getAndSet(T obj, long newValue)468 public final long getAndSet(T obj, long newValue) { 469 accessCheck(obj); 470 return U.getAndSetLong(obj, offset, newValue); 471 } 472 getAndAdd(T obj, long delta)473 public final long getAndAdd(T obj, long delta) { 474 accessCheck(obj); 475 return U.getAndAddLong(obj, offset, delta); 476 } 477 getAndIncrement(T obj)478 public final long getAndIncrement(T obj) { 479 return getAndAdd(obj, 1); 480 } 481 getAndDecrement(T obj)482 public final long getAndDecrement(T obj) { 483 return getAndAdd(obj, -1); 484 } 485 incrementAndGet(T obj)486 public final long incrementAndGet(T obj) { 487 return getAndAdd(obj, 1) + 1; 488 } 489 decrementAndGet(T obj)490 public final long decrementAndGet(T obj) { 491 return getAndAdd(obj, -1) - 1; 492 } 493 addAndGet(T obj, long delta)494 public final long addAndGet(T obj, long delta) { 495 return getAndAdd(obj, delta) + delta; 496 } 497 } 498 499 private static final class LockedUpdater<T> extends AtomicLongFieldUpdater<T> { 500 private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); 501 private final long offset; 502 /** 503 * if field is protected, the subclass constructing updater, else 504 * the same as tclass 505 */ 506 private final Class<?> cclass; 507 /** class holding the field */ 508 private final Class<T> tclass; 509 LockedUpdater(final Class<T> tclass, final String fieldName, final Class<?> caller)510 LockedUpdater(final Class<T> tclass, final String fieldName, 511 final Class<?> caller) { 512 Field field = null; 513 int modifiers = 0; 514 try { 515 field = tclass.getDeclaredField(fieldName); // Android-changed 516 modifiers = field.getModifiers(); 517 // BEGIN Android-removed 518 // sun.reflect.misc.ReflectUtil.ensureMemberAccess( 519 // caller, tclass, null, modifiers); 520 // ClassLoader cl = tclass.getClassLoader(); 521 // ClassLoader ccl = caller.getClassLoader(); 522 // if ((ccl != null) && (ccl != cl) && 523 // ((cl == null) || !isAncestor(cl, ccl))) { 524 // sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); 525 // } 526 // END Android-removed 527 // BEGIN Android-removed 528 // } catch (PrivilegedActionException pae) { 529 // throw new RuntimeException(pae.getException()); 530 // END Android-removed 531 } catch (Exception ex) { 532 throw new RuntimeException(ex); 533 } 534 535 if (field.getType() != long.class) 536 throw new IllegalArgumentException("Must be long type"); 537 538 if (!Modifier.isVolatile(modifiers)) 539 throw new IllegalArgumentException("Must be volatile type"); 540 541 this.cclass = (Modifier.isProtected(modifiers)) ? caller : tclass; 542 this.tclass = tclass; 543 this.offset = U.objectFieldOffset(field); 544 } 545 546 /** 547 * Checks that target argument is instance of cclass. On 548 * failure, throws cause. 549 */ accessCheck(T obj)550 private final void accessCheck(T obj) { 551 if (!cclass.isInstance(obj)) 552 throw accessCheckException(obj); 553 } 554 555 /** 556 * Returns access exception if accessCheck failed due to 557 * protected access, else ClassCastException. 558 */ accessCheckException(T obj)559 private final RuntimeException accessCheckException(T obj) { 560 if (cclass == tclass) 561 return new ClassCastException(); 562 else 563 return new RuntimeException( 564 new IllegalAccessException( 565 "Class " + 566 cclass.getName() + 567 " can not access a protected member of class " + 568 tclass.getName() + 569 " using an instance of " + 570 obj.getClass().getName())); 571 } 572 compareAndSet(T obj, long expect, long update)573 public final boolean compareAndSet(T obj, long expect, long update) { 574 accessCheck(obj); 575 synchronized (this) { 576 long v = U.getLong(obj, offset); 577 if (v != expect) 578 return false; 579 U.putLong(obj, offset, update); 580 return true; 581 } 582 } 583 weakCompareAndSet(T obj, long expect, long update)584 public final boolean weakCompareAndSet(T obj, long expect, long update) { 585 return compareAndSet(obj, expect, update); 586 } 587 set(T obj, long newValue)588 public final void set(T obj, long newValue) { 589 accessCheck(obj); 590 synchronized (this) { 591 U.putLong(obj, offset, newValue); 592 } 593 } 594 lazySet(T obj, long newValue)595 public final void lazySet(T obj, long newValue) { 596 set(obj, newValue); 597 } 598 get(T obj)599 public final long get(T obj) { 600 accessCheck(obj); 601 synchronized (this) { 602 return U.getLong(obj, offset); 603 } 604 } 605 } 606 607 // BEGIN Android-removed 608 // /** 609 // * Returns true if the second classloader can be found in the first 610 // * classloader's delegation chain. 611 // * Equivalent to the inaccessible: first.isAncestor(second). 612 // */ 613 // static boolean isAncestor(ClassLoader first, ClassLoader second) { 614 // ClassLoader acl = first; 615 // do { 616 // acl = acl.getParent(); 617 // if (second == acl) { 618 // return true; 619 // } 620 // } while (acl != null); 621 // return false; 622 // } 623 // END Android-removed 624 } 625