package jvstm.test.point.runners; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import junit.framework.Assert; import jvstm.CommitException; import jvstm.SuspendedTransaction; import jvstm.Transaction; import jvstm.test.point.core.Point; public class RunRwWithRwConflictDisjointFields{ private static final ScheduledExecutorService executor = Executors.newScheduledThreadPool(4); public static <T extends Number> void performTest(final Point<T> p) throws Exception{ final long initX = p.getX().longValue(); final long initY = p.getY().longValue(); final Transaction rwTrx1 = Transaction.begin(false); SuspendedTransaction r1 = rwTrx1.suspendTx(); // // ThreadLocal -> rwTrx2 // final Transaction rwTrx2 = Transaction.begin(false); Assert.assertEquals(initY, p.getY().longValue()); p.setY(update(initY)); Assert.assertEquals(update(initY), p.getY().longValue()); final SuspendedTransaction r2Token = rwTrx2.suspendTx(); // // ThreadLocal -> rwTrx1 // rwTrx1.resume(r1); long currX = p.getX().longValue(); Assert.assertEquals(initX, currX); p.setX(update(initX)); Assert.assertEquals(update(initX), p.getX().longValue()); final SuspendedTransaction r1Token = rwTrx1.suspendTx(); // // Main thread starts a new transaction // currX = p.getX().longValue(); long currY = p.getY().longValue(); Assert.assertEquals(initX, currX); Assert.assertEquals(initY, currY); // // ThreadLocal -> rwTrx2 // final Future<?> fT2 = executor.submit(new Runnable() { public void run() { rwTrx2.resume(r2Token); Transaction.commit(); // // Starts a new transaction // long currX = p.getX().longValue(); long currY = p.getY().longValue(); Assert.assertEquals(initX, currX); Assert.assertEquals(update(initY), currY); }}); // // ThreadLocal -> rwTrx1 // final Future<?> fT1 = executor.schedule(new Runnable() { public void run() { rwTrx1.resume(r1Token); long currX = p.getX().longValue(); Assert.assertEquals(update(initX), currX); try{ Transaction.commit(); // The commit succeeds with conflict detection granularity of word-level Assert.assertTrue(false); // Fields with different VBoxes will not conflict }catch(CommitException e){ Assert.assertTrue(true); rwTrx1.abortTx(); } }}, 1000, TimeUnit.MILLISECONDS); fT2.get(); fT1.get(); // // Main thread starts a new transaction // Assert.assertEquals(initX, p.getX().longValue()); Assert.assertEquals(update(initY), p.getY().longValue()); } private static long update(long src){ return (src*4+6)/2; } }