18f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle/*
28f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Written by Doug Lea with assistance from members of JCP JSR-166
38f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Expert Group and released to the public domain, as explained at
48f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * http://creativecommons.org/publicdomain/zero/1.0/
58f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Other contributors include Andrew Wright, Jeffrey Hayes,
68f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle * Pat Fisher, Mike Judd.
78f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle */
88f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
98f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravlepackage jsr166;
108f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
118f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravleimport java.util.concurrent.atomic.AtomicStampedReference;
128f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
138e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport junit.framework.Test;
148e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamathimport junit.framework.TestSuite;
158e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath
168f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravlepublic class AtomicStampedReferenceTest extends JSR166TestCase {
178e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    // android-note: Removed because the CTS runner does a bad job of
188e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    // retrying tests that have suite() declarations.
198e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    //
208e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    // public static void main(String[] args) {
218e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    //     main(suite(), args);
228e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    // }
238e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    // public static Test suite() {
24e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak    //     return new TestSuite(AtomicStampedReferenceTest.class);
258e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath    // }
268f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
278f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
288f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * constructor initializes to given reference and stamp
298f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
308f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void testConstructor() {
318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        AtomicStampedReference ai = new AtomicStampedReference(one, 0);
328f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(one, ai.getReference());
338f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(0, ai.getStamp());
348f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        AtomicStampedReference a2 = new AtomicStampedReference(null, 1);
358f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertNull(a2.getReference());
368f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(1, a2.getStamp());
378f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
388f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
398f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
408f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * get returns the last values of reference and stamp set
418f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
428f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void testGetSet() {
438f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        int[] mark = new int[1];
448f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        AtomicStampedReference ai = new AtomicStampedReference(one, 0);
458f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(one, ai.getReference());
468f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(0, ai.getStamp());
478f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(one, ai.get(mark));
488f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(0, mark[0]);
498f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        ai.set(two, 0);
508f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(two, ai.getReference());
518f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(0, ai.getStamp());
528f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(two, ai.get(mark));
538f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(0, mark[0]);
548f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        ai.set(one, 1);
558f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(one, ai.getReference());
568f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(1, ai.getStamp());
578f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(one, ai.get(mark));
588f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(1, mark[0]);
598f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
608f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
618f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
628f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * attemptStamp succeeds in single thread
638f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
648f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void testAttemptStamp() {
658f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        int[] mark = new int[1];
668f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        AtomicStampedReference ai = new AtomicStampedReference(one, 0);
678f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(0, ai.getStamp());
688f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertTrue(ai.attemptStamp(one, 1));
698f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(1, ai.getStamp());
708f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(one, ai.get(mark));
718f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(1, mark[0]);
728f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
738f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
748f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
758f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * compareAndSet succeeds in changing values if equal to expected reference
768f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * and stamp else fails
778f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
788f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void testCompareAndSet() {
798f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        int[] mark = new int[1];
808f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        AtomicStampedReference ai = new AtomicStampedReference(one, 0);
818f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(one, ai.get(mark));
828f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(0, ai.getStamp());
838f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(0, mark[0]);
848f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
858f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertTrue(ai.compareAndSet(one, two, 0, 0));
868f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(two, ai.get(mark));
878f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(0, mark[0]);
888f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
898f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertTrue(ai.compareAndSet(two, m3, 0, 1));
908f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(m3, ai.get(mark));
918f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(1, mark[0]);
928f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
938f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertFalse(ai.compareAndSet(two, m3, 1, 1));
948f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(m3, ai.get(mark));
958f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(1, mark[0]);
968f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
978f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
988f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
998f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * compareAndSet in one thread enables another waiting for reference value
1008f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * to succeed
1018f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
1028f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void testCompareAndSetInMultipleThreads() throws Exception {
1038f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        final AtomicStampedReference ai = new AtomicStampedReference(one, 0);
1048f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        Thread t = new Thread(new CheckedRunnable() {
1058f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            public void realRun() {
1068f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                while (!ai.compareAndSet(two, three, 0, 0))
1078f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                    Thread.yield();
1088f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }});
1098f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
1108f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        t.start();
1118f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertTrue(ai.compareAndSet(one, two, 0, 0));
1128f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        t.join(LONG_DELAY_MS);
1138f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertFalse(t.isAlive());
1148f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(three, ai.getReference());
1158f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(0, ai.getStamp());
1168f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
1178f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
1188f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
1198f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * compareAndSet in one thread enables another waiting for stamp value
1208f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * to succeed
1218f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
1228f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void testCompareAndSetInMultipleThreads2() throws Exception {
1238f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        final AtomicStampedReference ai = new AtomicStampedReference(one, 0);
1248f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        Thread t = new Thread(new CheckedRunnable() {
1258f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            public void realRun() {
1268f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                while (!ai.compareAndSet(one, one, 1, 2))
1278f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle                    Thread.yield();
1288f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle            }});
1298f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
1308f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        t.start();
1318f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertTrue(ai.compareAndSet(one, one, 0, 1));
1328f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        t.join(LONG_DELAY_MS);
1338f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertFalse(t.isAlive());
1348f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(one, ai.getReference());
1358f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(2, ai.getStamp());
1368f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
1378f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
1388f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    /**
1398f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * repeated weakCompareAndSet succeeds in changing values when equal
1408f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     * to expected
1418f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle     */
1428f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    public void testWeakCompareAndSet() {
1438f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        int[] mark = new int[1];
1448f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        AtomicStampedReference ai = new AtomicStampedReference(one, 0);
1458f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(one, ai.get(mark));
1468f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(0, ai.getStamp());
1478f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(0, mark[0]);
1488f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
1498e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        do {} while (!ai.weakCompareAndSet(one, two, 0, 0));
1508f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(two, ai.get(mark));
1518f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(0, mark[0]);
1528f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
1538e9a0e92906742b17eb08d7fb83cca91965f9b8eNarayan Kamath        do {} while (!ai.weakCompareAndSet(two, m3, 0, 1));
1548f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertSame(m3, ai.get(mark));
1558f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle        assertEquals(1, mark[0]);
1568f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle    }
1578f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle
1588f0d92bba199d906c70a5e40d7f3516c1a424117Calin Juravle}
159