11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Written by Doug Lea and Martin Buchholz with assistance from 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * members of JCP JSR-166 Expert Group and released to the public 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * domain, as explained at 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://creativecommons.org/publicdomain/zero/1.0/ 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Source: 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/test/tck-jsr166e/AtomicDoubleArrayTest.java?revision=1.13 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * (Modified to adapt to guava coding conventions) 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.util.concurrent; 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport junit.framework.*; 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Arrays; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unit test for {@link AtomicDoubleArray}. 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class AtomicDoubleArrayTest extends JSR166TestCase { 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final double[] VALUES = { 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Double.NEGATIVE_INFINITY, 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert -Double.MAX_VALUE, 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert (double) Long.MIN_VALUE, 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert (double) Integer.MIN_VALUE, 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert -Math.PI, 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert -1.0, 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert -Double.MIN_VALUE, 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert -0.0, 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert +0.0, 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Double.MIN_VALUE, 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1.0, 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Math.PI, 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert (double) Integer.MAX_VALUE, 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert (double) Long.MAX_VALUE, 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Double.MAX_VALUE, 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Double.POSITIVE_INFINITY, 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Double.NaN, 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Float.MAX_VALUE, 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** The notion of equality used by AtomicDoubleArray */ 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static boolean bitEquals(double x, double y) { 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Double.doubleToRawLongBits(x) == Double.doubleToRawLongBits(y); 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static void assertBitEquals(double x, double y) { 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(Double.doubleToRawLongBits(x), 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Double.doubleToRawLongBits(y)); 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constructor creates array of given size with all elements zero 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testConstructor() { 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray aa = new AtomicDoubleArray(SIZE); 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < SIZE; i++) { 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(0.0, aa.get(i)); 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constructor with null array throws NPE 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testConstructor2NPE() { 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert double[] a = null; 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray aa = new AtomicDoubleArray(a); 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert shouldThrow(); 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (NullPointerException success) {} 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constructor with array is of same size and has all elements 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testConstructor2() { 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray aa = new AtomicDoubleArray(VALUES); 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(VALUES.length, aa.length()); 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < VALUES.length; i++) { 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(VALUES[i], aa.get(i)); 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constructor with empty array has size 0 and contains no elements 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testConstructorEmptyArray() { 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray aa = new AtomicDoubleArray(new double[0]); 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, aa.length()); 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert aa.get(0); 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert shouldThrow(); 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IndexOutOfBoundsException success) {} 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constructor with length zero has size 0 and contains no elements 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testConstructorZeroLength() { 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray aa = new AtomicDoubleArray(0); 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, aa.length()); 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert aa.get(0); 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert shouldThrow(); 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IndexOutOfBoundsException success) {} 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * get and set for out of bound indices throw IndexOutOfBoundsException 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testIndexing() { 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray aa = new AtomicDoubleArray(SIZE); 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int index : new int[] { -1, SIZE }) { 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert aa.get(index); 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert shouldThrow(); 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IndexOutOfBoundsException success) {} 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert aa.set(index, 1.0); 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert shouldThrow(); 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IndexOutOfBoundsException success) {} 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert aa.lazySet(index, 1.0); 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert shouldThrow(); 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IndexOutOfBoundsException success) {} 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert aa.compareAndSet(index, 1.0, 2.0); 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert shouldThrow(); 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IndexOutOfBoundsException success) {} 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert aa.weakCompareAndSet(index, 1.0, 2.0); 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert shouldThrow(); 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IndexOutOfBoundsException success) {} 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert aa.getAndAdd(index, 1.0); 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert shouldThrow(); 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IndexOutOfBoundsException success) {} 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert aa.addAndGet(index, 1.0); 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert shouldThrow(); 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IndexOutOfBoundsException success) {} 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * get returns the last value set at index 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testGetSet() { 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray aa = new AtomicDoubleArray(VALUES.length); 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < VALUES.length; i++) { 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(0.0, aa.get(i)); 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert aa.set(i, VALUES[i]); 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(VALUES[i], aa.get(i)); 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert aa.set(i, -3.0); 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(-3.0, aa.get(i)); 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * get returns the last value lazySet at index by same thread 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testGetLazySet() { 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray aa = new AtomicDoubleArray(VALUES.length); 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < VALUES.length; i++) { 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(0.0, aa.get(i)); 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert aa.lazySet(i, VALUES[i]); 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(VALUES[i], aa.get(i)); 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert aa.lazySet(i, -3.0); 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(-3.0, aa.get(i)); 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * compareAndSet succeeds in changing value if equal to expected else fails 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testCompareAndSet() { 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray aa = new AtomicDoubleArray(SIZE); 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i : new int[] { 0, SIZE - 1}) { 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert double prev = 0.0; 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert double unused = Math.E + Math.PI; 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (double x : VALUES) { 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(prev, aa.get(i)); 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(aa.compareAndSet(i, unused, x)); 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(prev, aa.get(i)); 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(aa.compareAndSet(i, prev, x)); 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(x, aa.get(i)); 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert prev = x; 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * compareAndSet in one thread enables another waiting for value 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * to succeed 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testCompareAndSetInMultipleThreads() throws InterruptedException { 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final AtomicDoubleArray a = new AtomicDoubleArray(1); 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert a.set(0, 1.0); 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Thread t = newStartedThread(new CheckedRunnable() { 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void realRun() { 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (!a.compareAndSet(0, 2.0, 3.0)) { 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Thread.yield(); 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }}); 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(a.compareAndSet(0, 1.0, 2.0)); 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert awaitTermination(t); 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(3.0, a.get(0)); 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * repeated weakCompareAndSet succeeds in changing value when equal 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * to expected 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testWeakCompareAndSet() { 2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray aa = new AtomicDoubleArray(SIZE); 2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i : new int[] { 0, SIZE - 1}) { 2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert double prev = 0.0; 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert double unused = Math.E + Math.PI; 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (double x : VALUES) { 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(prev, aa.get(i)); 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(aa.weakCompareAndSet(i, unused, x)); 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(prev, aa.get(i)); 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (!aa.weakCompareAndSet(i, prev, x)) { 2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ; 2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(x, aa.get(i)); 2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert prev = x; 2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * getAndSet returns previous value and sets to given value at given index 2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testGetAndSet() { 2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray aa = new AtomicDoubleArray(SIZE); 2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i : new int[] { 0, SIZE - 1}) { 2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert double prev = 0.0; 2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (double x : VALUES) { 2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(prev, aa.getAndSet(i, x)); 2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert prev = x; 2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * getAndAdd returns previous value and adds given value 2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testGetAndAdd() { 2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray aa = new AtomicDoubleArray(SIZE); 2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i : new int[] { 0, SIZE - 1}) { 2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (double x : VALUES) { 2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (double y : VALUES) { 2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert aa.set(i, x); 2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert double z = aa.getAndAdd(i, y); 2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(x, z); 2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(x + y, aa.get(i)); 2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * addAndGet adds given value to current, and returns current value 2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testAddAndGet() { 2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray aa = new AtomicDoubleArray(SIZE); 2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i : new int[] { 0, SIZE - 1}) { 2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (double x : VALUES) { 2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (double y : VALUES) { 2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert aa.set(i, x); 2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert double z = aa.addAndGet(i, y); 2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(x + y, z); 2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(x + y, aa.get(i)); 2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static final long COUNTDOWN = 100000; 2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert class Counter extends CheckedRunnable { 2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final AtomicDoubleArray aa; 2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert volatile long counts; 2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Counter(AtomicDoubleArray a) { aa = a; } 2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void realRun() { 2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (;;) { 2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean done = true; 2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < aa.length(); i++) { 2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert double v = aa.get(i); 2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(v >= 0); 2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (v != 0) { 2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert done = false; 2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (aa.compareAndSet(i, v, v - 1.0)) { 3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ++counts; 3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (done) { 3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert break; 3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Multiple threads using same array of counters successfully 3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * update a number of times equal to total count 3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testCountingInMultipleThreads() throws InterruptedException { 3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final AtomicDoubleArray aa = new AtomicDoubleArray(SIZE); 3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < SIZE; i++) { 3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert aa.set(i, (double) COUNTDOWN); 3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Counter c1 = new Counter(aa); 3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Counter c2 = new Counter(aa); 3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Thread t1 = newStartedThread(c1); 3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Thread t2 = newStartedThread(c2); 3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert awaitTermination(t1); 3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert awaitTermination(t2); 3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(c1.counts + c2.counts, SIZE * COUNTDOWN); 3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * a deserialized serialized array holds same values 3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSerialization() throws Exception { 3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray x = new AtomicDoubleArray(SIZE); 3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < SIZE; i++) { 3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert x.set(i, (double) -i); 3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray y = serialClone(x); 3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(x != y); 3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(x.length(), y.length()); 3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < SIZE; i++) { 3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(x.get(i), y.get(i)); 3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray a = new AtomicDoubleArray(VALUES); 3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray b = serialClone(a); 3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(a.equals(b)); 3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(b.equals(a)); 3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(a.length(), b.length()); 3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < VALUES.length; i++) { 3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(a.get(i), b.get(i)); 3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * toString returns current value 3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testToString() { 3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray aa = new AtomicDoubleArray(VALUES); 3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(Arrays.toString(VALUES), aa.toString()); 3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals("[]", new AtomicDoubleArray(0).toString()); 3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals("[]", new AtomicDoubleArray(new double[0]).toString()); 3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * compareAndSet treats +0.0 and -0.0 as distinct values 3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testDistinctZeros() { 3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicDoubleArray aa = new AtomicDoubleArray(SIZE); 3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i : new int[] { 0, SIZE - 1}) { 3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(aa.compareAndSet(i, -0.0, 7.0)); 3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(aa.weakCompareAndSet(i, -0.0, 7.0)); 3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(+0.0, aa.get(i)); 3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(aa.compareAndSet(i, +0.0, -0.0)); 3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(-0.0, aa.get(i)); 3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(aa.compareAndSet(i, +0.0, 7.0)); 3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(aa.weakCompareAndSet(i, +0.0, 7.0)); 3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertBitEquals(-0.0, aa.get(i)); 3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 382