|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AtomicMarkableReference | Line # 20 | 16 | 11 | 96.3% |
0.962963
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AtomicMarkableReference.ReferenceBooleanPair | Line # 22 | 2 | 1 | 100% |
1.0
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (7) | |||
| Result | |||
|
0.6666667
|
AtomicMarkableReferenceTest.testGetSet
AtomicMarkableReferenceTest.testGetSet
|
1 PASS | |
|
0.53333336
|
AtomicMarkableReferenceTest.testWeakCompareAndSet
AtomicMarkableReferenceTest.testWeakCompareAndSet
|
1 PASS | |
|
0.53333336
|
AtomicMarkableReferenceTest.testCompareAndSet
AtomicMarkableReferenceTest.testCompareAndSet
|
1 PASS | |
|
0.53333336
|
AtomicMarkableReferenceTest.testAttemptMark
AtomicMarkableReferenceTest.testAttemptMark
|
1 PASS | |
|
0.46666667
|
AtomicMarkableReferenceTest.testCompareAndSetInMultipleThreads
AtomicMarkableReferenceTest.testCompareAndSetInMultipleThreads
|
1 PASS | |
|
0.46666667
|
AtomicMarkableReferenceTest.testCompareAndSetInMultipleThreads2
AtomicMarkableReferenceTest.testCompareAndSetInMultipleThreads2
|
1 PASS | |
|
0.36666667
|
AtomicMarkableReferenceTest.testConstructor
AtomicMarkableReferenceTest.testConstructor
|
1 PASS | |
| 1 | /* | |
| 2 | * Written by Doug Lea with assistance from members of JCP JSR-166 | |
| 3 | * Expert Group and released to the public domain, as explained at | |
| 4 | * http://creativecommons.org/licenses/publicdomain | |
| 5 | */ | |
| 6 | ||
| 7 | package edu.emory.mathcs.backport.java.util.concurrent.atomic; | |
| 8 | ||
| 9 | /** | |
| 10 | * An {@code AtomicMarkableReference} maintains an object reference | |
| 11 | * along with a mark bit, that can be updated atomically. | |
| 12 | * <p> | |
| 13 | * <p> Implementation note. This implementation maintains markable | |
| 14 | * references by creating internal objects representing "boxed" | |
| 15 | * [reference, boolean] pairs. | |
| 16 | * | |
| 17 | * @since 1.5 | |
| 18 | * @author Doug Lea | |
| 19 | */ | |
| 20 | public class AtomicMarkableReference { | |
| 21 | ||
| 22 | private static class ReferenceBooleanPair { | |
| 23 | private final Object reference; | |
| 24 | private final boolean bit; | |
| 25 | 19 |
ReferenceBooleanPair(Object r, boolean i) { |
| 26 | 19 | reference = r; bit = i; |
| 27 | } | |
| 28 | } | |
| 29 | ||
| 30 | private final AtomicReference atomicRef; | |
| 31 | ||
| 32 | /** | |
| 33 | * Creates a new {@code AtomicMarkableReference} with the given | |
| 34 | * initial values. | |
| 35 | * | |
| 36 | * @param initialRef the initial reference | |
| 37 | * @param initialMark the initial mark | |
| 38 | */ | |
| 39 | 8 |
public AtomicMarkableReference(Object initialRef, boolean initialMark) { |
| 40 | 8 | atomicRef = new AtomicReference(new ReferenceBooleanPair(initialRef, initialMark)); |
| 41 | } | |
| 42 | ||
| 43 | 41 |
private ReferenceBooleanPair getPair() { |
| 44 | 41 | return (ReferenceBooleanPair)atomicRef.get(); |
| 45 | } | |
| 46 | ||
| 47 | /** | |
| 48 | * Returns the current value of the reference. | |
| 49 | * | |
| 50 | * @return the current value of the reference | |
| 51 | */ | |
| 52 | 7 |
public Object getReference() { |
| 53 | 7 | return getPair().reference; |
| 54 | } | |
| 55 | ||
| 56 | /** | |
| 57 | * Returns the current value of the mark. | |
| 58 | * | |
| 59 | * @return the current value of the mark | |
| 60 | */ | |
| 61 | 11 |
public boolean isMarked() { |
| 62 | 11 | return getPair().bit; |
| 63 | } | |
| 64 | ||
| 65 | /** | |
| 66 | * Returns the current values of both the reference and the mark. | |
| 67 | * Typical usage is {@code boolean[1] holder; ref = v.get(holder); }. | |
| 68 | * | |
| 69 | * @param markHolder an array of size of at least one. On return, | |
| 70 | * {@code markholder[0]} will hold the value of the mark. | |
| 71 | * @return the current value of the reference | |
| 72 | */ | |
| 73 | 11 |
public Object get(boolean[] markHolder) { |
| 74 | 11 | ReferenceBooleanPair p = getPair(); |
| 75 | 11 | markHolder[0] = p.bit; |
| 76 | 11 | return p.reference; |
| 77 | } | |
| 78 | ||
| 79 | /** | |
| 80 | * Atomically sets the value of both the reference and mark | |
| 81 | * to the given update values if the | |
| 82 | * current reference is {@code ==} to the expected reference | |
| 83 | * and the current mark is equal to the expected mark. | |
| 84 | * | |
| 85 | * <p>May <a href="package-summary.html#Spurious">fail spuriously</a> | |
| 86 | * and does not provide ordering guarantees, so is only rarely an | |
| 87 | * appropriate alternative to {@code compareAndSet}. | |
| 88 | * | |
| 89 | * @param expectedReference the expected value of the reference | |
| 90 | * @param newReference the new value for the reference | |
| 91 | * @param expectedMark the expected value of the mark | |
| 92 | * @param newMark the new value for the mark | |
| 93 | * @return true if successful | |
| 94 | */ | |
| 95 | 2 |
public boolean weakCompareAndSet(Object expectedReference, |
| 96 | Object newReference, | |
| 97 | boolean expectedMark, | |
| 98 | boolean newMark) { | |
| 99 | 2 | ReferenceBooleanPair current = getPair(); |
| 100 | 2 | return expectedReference == current.reference && |
| 101 | expectedMark == current.bit && | |
| 102 | ((newReference == current.reference && newMark == current.bit) || | |
| 103 | atomicRef.weakCompareAndSet(current, | |
| 104 | new ReferenceBooleanPair(newReference, | |
| 105 | newMark))); | |
| 106 | } | |
| 107 | ||
| 108 | /** | |
| 109 | * Atomically sets the value of both the reference and mark | |
| 110 | * to the given update values if the | |
| 111 | * current reference is {@code ==} to the expected reference | |
| 112 | * and the current mark is equal to the expected mark. | |
| 113 | * | |
| 114 | * @param expectedReference the expected value of the reference | |
| 115 | * @param newReference the new value for the reference | |
| 116 | * @param expectedMark the expected value of the mark | |
| 117 | * @param newMark the new value for the mark | |
| 118 | * @return true if successful | |
| 119 | */ | |
| 120 | 7 |
public boolean compareAndSet(Object expectedReference, |
| 121 | Object newReference, | |
| 122 | boolean expectedMark, | |
| 123 | boolean newMark) { | |
| 124 | 7 | ReferenceBooleanPair current = getPair(); |
| 125 | 7 | return expectedReference == current.reference && |
| 126 | expectedMark == current.bit && | |
| 127 | ((newReference == current.reference && newMark == current.bit) || | |
| 128 | atomicRef.compareAndSet(current, | |
| 129 | new ReferenceBooleanPair(newReference, | |
| 130 | newMark))); | |
| 131 | } | |
| 132 | ||
| 133 | /** | |
| 134 | * Unconditionally sets the value of both the reference and mark. | |
| 135 | * | |
| 136 | * @param newReference the new value for the reference | |
| 137 | * @param newMark the new value for the mark | |
| 138 | */ | |
| 139 | 2 |
public void set(Object newReference, boolean newMark) { |
| 140 | 2 | ReferenceBooleanPair current = getPair(); |
| 141 | 2 | if (newReference != current.reference || newMark != current.bit) |
| 142 | 2 | atomicRef.set(new ReferenceBooleanPair(newReference, newMark)); |
| 143 | } | |
| 144 | ||
| 145 | /** | |
| 146 | * Atomically sets the value of the mark to the given update value | |
| 147 | * if the current reference is {@code ==} to the expected | |
| 148 | * reference. Any given invocation of this operation may fail | |
| 149 | * (return {@code false}) spuriously, but repeated invocation | |
| 150 | * when the current value holds the expected value and no other | |
| 151 | * thread is also attempting to set the value will eventually | |
| 152 | * succeed. | |
| 153 | * | |
| 154 | * @param expectedReference the expected value of the reference | |
| 155 | * @param newMark the new value for the mark | |
| 156 | * @return true if successful | |
| 157 | */ | |