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/publicdomain/zero/1.0/
5  * Other contributors include Andrew Wright, Jeffrey Hayes,
6  * Pat Fisher, Mike Judd.
7  */
8 
9 package jsr166;
10 
11 import java.util.concurrent.atomic.AtomicMarkableReference;
12 
13 import junit.framework.Test;
14 import junit.framework.TestSuite;
15 
16 public class AtomicMarkableReferenceTest extends JSR166TestCase {
17     // android-note: Removed because the CTS runner does a bad job of
18     // retrying tests that have suite() declarations.
19     //
20     // public static void main(String[] args) {
21     //     main(suite(), args);
22     // }
23     // public static Test suite() {
24     //     return new TestSuite(AtomicMarkableReferenceTest.class);
25     // }
26 
27     /**
28      * constructor initializes to given reference and mark
29      */
testConstructor()30     public void testConstructor() {
31         AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
32         assertSame(one, ai.getReference());
33         assertFalse(ai.isMarked());
34         AtomicMarkableReference a2 = new AtomicMarkableReference(null, true);
35         assertNull(a2.getReference());
36         assertTrue(a2.isMarked());
37     }
38 
39     /**
40      * get returns the last values of reference and mark set
41      */
testGetSet()42     public void testGetSet() {
43         boolean[] mark = new boolean[1];
44         AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
45         assertSame(one, ai.getReference());
46         assertFalse(ai.isMarked());
47         assertSame(one, ai.get(mark));
48         assertFalse(mark[0]);
49         ai.set(two, false);
50         assertSame(two, ai.getReference());
51         assertFalse(ai.isMarked());
52         assertSame(two, ai.get(mark));
53         assertFalse(mark[0]);
54         ai.set(one, true);
55         assertSame(one, ai.getReference());
56         assertTrue(ai.isMarked());
57         assertSame(one, ai.get(mark));
58         assertTrue(mark[0]);
59     }
60 
61     /**
62      * attemptMark succeeds in single thread
63      */
testAttemptMark()64     public void testAttemptMark() {
65         boolean[] mark = new boolean[1];
66         AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
67         assertFalse(ai.isMarked());
68         assertTrue(ai.attemptMark(one, true));
69         assertTrue(ai.isMarked());
70         assertSame(one, ai.get(mark));
71         assertTrue(mark[0]);
72     }
73 
74     /**
75      * compareAndSet succeeds in changing values if equal to expected reference
76      * and mark else fails
77      */
testCompareAndSet()78     public void testCompareAndSet() {
79         boolean[] mark = new boolean[1];
80         AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
81         assertSame(one, ai.get(mark));
82         assertFalse(ai.isMarked());
83         assertFalse(mark[0]);
84 
85         assertTrue(ai.compareAndSet(one, two, false, false));
86         assertSame(two, ai.get(mark));
87         assertFalse(mark[0]);
88 
89         assertTrue(ai.compareAndSet(two, m3, false, true));
90         assertSame(m3, ai.get(mark));
91         assertTrue(mark[0]);
92 
93         assertFalse(ai.compareAndSet(two, m3, true, true));
94         assertSame(m3, ai.get(mark));
95         assertTrue(mark[0]);
96     }
97 
98     /**
99      * compareAndSet in one thread enables another waiting for reference value
100      * to succeed
101      */
testCompareAndSetInMultipleThreads()102     public void testCompareAndSetInMultipleThreads() throws Exception {
103         final AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
104         Thread t = new Thread(new CheckedRunnable() {
105             public void realRun() {
106                 while (!ai.compareAndSet(two, three, false, false))
107                     Thread.yield();
108             }});
109 
110         t.start();
111         assertTrue(ai.compareAndSet(one, two, false, false));
112         t.join(LONG_DELAY_MS);
113         assertFalse(t.isAlive());
114         assertSame(three, ai.getReference());
115         assertFalse(ai.isMarked());
116     }
117 
118     /**
119      * compareAndSet in one thread enables another waiting for mark value
120      * to succeed
121      */
testCompareAndSetInMultipleThreads2()122     public void testCompareAndSetInMultipleThreads2() throws Exception {
123         final AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
124         Thread t = new Thread(new CheckedRunnable() {
125             public void realRun() {
126                 while (!ai.compareAndSet(one, one, true, false))
127                     Thread.yield();
128             }});
129 
130         t.start();
131         assertTrue(ai.compareAndSet(one, one, false, true));
132         t.join(LONG_DELAY_MS);
133         assertFalse(t.isAlive());
134         assertSame(one, ai.getReference());
135         assertFalse(ai.isMarked());
136     }
137 
138     /**
139      * repeated weakCompareAndSet succeeds in changing values when equal
140      * to expected
141      */
testWeakCompareAndSet()142     public void testWeakCompareAndSet() {
143         boolean[] mark = new boolean[1];
144         AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
145         assertSame(one, ai.get(mark));
146         assertFalse(ai.isMarked());
147         assertFalse(mark[0]);
148 
149         do {} while (!ai.weakCompareAndSet(one, two, false, false));
150         assertSame(two, ai.get(mark));
151         assertFalse(mark[0]);
152 
153         do {} while (!ai.weakCompareAndSet(two, m3, false, true));
154         assertSame(m3, ai.get(mark));
155         assertTrue(mark[0]);
156     }
157 
158 }
159