Parallel nested transactions had a bug on the abort procedure.
[jvstm.git] / examples / parallel-nesting / simple / AbortedParallelTxTest.java
blob192843bebacdf3a4cd91a61eb2e94ad80b0e42aa
1 package simple;
3 import java.util.ArrayList;
4 import java.util.List;
6 import jvstm.CommitException;
7 import jvstm.ParallelTask;
8 import jvstm.Transaction;
9 import jvstm.VBox;
11 /**
12 * Test the following scenario
13 * A writes x=1
14 * A spawns B
15 * B spawns C e D
16 * C writes x=2
17 * C reads y=0
18 * D writes y=1
19 * D commits
20 * C aborts
21 * at this point, another top level transaction Z tries to write to x and acquires ownership of the VBox
22 * when in fact the ownership belonged to A
25 * @author nmld
28 public class AbortedParallelTxTest {
30 protected static final VBox<Integer> x = new VBox<Integer>(0);
31 protected static final VBox<Integer> y = new VBox<Integer>(0);
33 public static class TopLevelA extends Thread {
35 public void run() {
36 Transaction.begin(false);
37 try {
38 int valX = x.get();
39 x.put(valX + 1);
41 List<ParallelTask<Void>> tasks = new ArrayList<ParallelTask<Void>>();
42 tasks.add(new NestedB());
43 Transaction.current().manageNestedParallelTxs(tasks);
45 Transaction.commit();
47 throw new AssertionError("TopLevelA should not commit because of Z");
49 } catch (CommitException ce) {
50 Transaction.abort();
55 public static class NestedB extends ParallelTask<Void> {
57 @Override
58 public Void execute() throws Throwable {
59 List<ParallelTask<Void>> tasks = new ArrayList<ParallelTask<Void>>();
60 tasks.add(new NestedC());
61 tasks.add(new NestedD());
62 Transaction.current().manageNestedParallelTxs(tasks);
63 return null;
68 public static class NestedC extends ParallelTask<Void> {
70 private boolean isRepeating = false;
72 @Override
73 public Void execute() throws Throwable {
74 if (isRepeating) {
75 Thread.sleep(3000);
78 int valX = x.get();
79 x.put(valX + 1);
80 int valY = y.get();
82 if (valX != 1) {
83 throw new AssertionError("NestedC read valX != 1: " + valX);
85 if (!isRepeating && valY != 0) {
86 throw new AssertionError("NestedC was not yet aborted, yet it read valY != 0: " + valY);
88 if (isRepeating && valY != 1) {
89 throw new AssertionError("NestedC was already aborted, yet it read valY != 1: " + valY);
92 isRepeating = true;
94 Thread.sleep(750);
96 return null;
101 public static class NestedD extends ParallelTask<Void> {
103 @Override
104 public Void execute() throws Throwable {
105 Thread.sleep(500);
107 int valY = y.get();
108 y.put(valY + 1);
110 if (valY != 0) {
111 throw new AssertionError("NestedD read valY != 0: " + valY);
114 return null;
119 public static class TopLevelZ extends Thread {
121 public void run() {
122 try {
124 Transaction.begin(false);
125 Thread.sleep(2000);
127 int valX = x.get();
128 x.put(valX + 1);
129 Transaction.commit();
131 } catch (InterruptedException e) {
137 public static void main(String[] args) throws InterruptedException {
138 TopLevelA A = new TopLevelA();
139 TopLevelZ Z = new TopLevelZ();
140 A.start();
141 Z.start();
142 A.join();
143 Z.join();
144 if (x.get() != 1) {
145 throw new AssertionError("Check in the end verified that x != 1");
147 if (y.get() != 0) {
148 throw new AssertionError("Check in the end verified that y != 0");
151 System.out.println("Successful test");