add source code that does not have location annotations.
[IRC.git] / Robust / Transactions / src / Transaction.java
1 /*
2  * Transaction.java
3  *
4  * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, Santa
5  * Clara, California 95054, U.S.A.  All rights reserved.  
6  * 
7  * Sun Microsystems, Inc. has intellectual property rights relating to
8  * technology embodied in the product that is described in this
9  * document.  In particular, and without limitation, these
10  * intellectual property rights may include one or more of the
11  * U.S. patents listed at http://www.sun.com/patents and one or more
12  * additional patents or pending patent applications in the U.S. and
13  * in other countries.
14  * 
15  * U.S. Government Rights - Commercial software.
16  * Government users are subject to the Sun Microsystems, Inc. standard
17  * license agreement and applicable provisions of the FAR and its
18  * supplements.  Use is subject to license terms.  Sun, Sun
19  * Microsystems, the Sun logo and Java are trademarks or registered
20  * trademarks of Sun Microsystems, Inc. in the U.S. and other
21  * countries.  
22  * 
23  * This product is covered and controlled by U.S. Export Control laws
24  * and may be subject to the export or import laws in other countries.
25  * Nuclear, missile, chemical biological weapons or nuclear maritime
26  * end uses or end users, whether direct or indirect, are strictly
27  * prohibited.  Export or reexport to countries subject to
28  * U.S. embargo or to entities identified on U.S. export exclusion
29  * lists, including, but not limited to, the denied persons and
30  * specially designated nationals lists is strictly prohibited.
31  */
32
33 package dstm2;
34
35 import dstm2.exceptions.PanicException;
36 import java.util.concurrent.atomic.AtomicReference;
37 import java.util.concurrent.atomic.AtomicInteger;
38 import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
39
40 /**
41  * Transaction.java
42  * Keeps a transaction's status and contention manager.
43  */
44
45 public class Transaction implements NewInterface {
46   
47   /**
48    * Possible transaction status
49    **/
50   //public enum Status {ABORTED, ACTIVE, COMMITTED};
51   
52   
53   public enum Status {ABORTED, ACTIVE, COMMITTED};
54   
55   /**
56    * Predefined committed transaction
57    */
58   public static Transaction COMMITTED = new Transaction(Status.COMMITTED);
59   /**
60    * Predefined orted transaction
61    */
62   public static Transaction ABORTED   = new Transaction(Status.ABORTED);
63   
64   /**
65    * Is transaction waiting for another?
66    */
67   public boolean waiting = false;
68   
69   /**
70    * Number of times this transaction tried
71    */
72   public int attempts = 0;
73   
74   /**
75    * Number of unique memory references so far.
76    */
77   public int memRefs = 0;
78   
79   /**
80    * Time in nanos when transaction started
81    */
82   public long startTime = 0;
83   /**
84    * Time in nanos when transaction committed or aborted
85    */
86   public long stopTime = 0;
87   
88   // generate unique ids
89   private static AtomicInteger unique = new AtomicInteger(100);
90   
91   /** Updater for status */
92   /*private static final
93       AtomicReferenceFieldUpdater<Transaction, Status>
94       statusUpdater = AtomicReferenceFieldUpdater.newUpdater
95       (Transaction.class, Status.class, "status");*/
96   
97   protected static final
98       AtomicReferenceFieldUpdater<Transaction, Status>
99       statusUpdater = AtomicReferenceFieldUpdater.newUpdater
100       (Transaction.class, Status.class, "status");
101   
102   
103   private volatile Status status;
104   
105   private long id;
106   
107   private ContentionManager manager;
108   
109   /**
110    * Creates a new, active transaction.
111    */
112   public Transaction() {
113     this.status = Status.ACTIVE;
114     this.id = this.startTime = System.nanoTime();
115     this.manager = Thread.getContentionManager();
116   }
117   
118   /**
119    * Creates a new transaction with given status.
120    * @param myStatus active, committed, or aborted
121    */
122   private Transaction(Transaction.Status myStatus) {
123     this.status = myStatus;
124     this.startTime = 0;
125   }
126   
127   /**
128    * Access the transaction's current status.
129    * @return current transaction status
130    */
131   public Status getStatus() {
132     return status;
133   }
134   
135   /**
136    * Tests whether transaction is active.
137    * @return whether transaction is active
138    */
139   public boolean isActive() {
140     return this.getStatus() == Status.ACTIVE;
141   }
142   
143   /**
144    * Tests whether transaction is aborted.
145    * @return whether transaction is aborted
146    */
147   public boolean isAborted() {
148     return this.getStatus() == Status.ABORTED;
149   }
150   
151   /**
152    * Tests whether transaction is committed.
153    * @return whether transaction is committed
154    */
155   public boolean isCommitted() {
156     return (this.getStatus() == Status.COMMITTED);
157   }
158   
159   /**
160    * Tests whether transaction is committed or active.
161    * @return whether transaction is committed or active
162    */
163   public boolean validate() {
164     Status status = this.getStatus();
165     switch (status) {
166       case COMMITTED:
167         throw new PanicException("committed transaction still running");
168       case ACTIVE:
169         return true;
170       case ABORTED:
171         return false;
172       default:
173         throw new PanicException("unexpected transaction state: " + status);
174     }
175   }
176   
177   /**
178    * Tries to commit transaction
179    * @return whether transaction was committed
180    */
181   public boolean commit() {
182     try {
183       while (this.getStatus() == Status.ACTIVE) {
184         if (statusUpdater.compareAndSet(this,
185             Status.ACTIVE,
186             Status.COMMITTED)) {
187           return true;
188         }
189       }
190       return false;
191     } finally {
192       wakeUp();
193     }
194   }
195   
196   /**
197    * Tries to abort transaction
198    * @return whether transaction was aborted (not necessarily by this call)
199    */
200   public boolean abort() {
201     try {
202       while (this.getStatus() == Status.ACTIVE) {
203         if (statusUpdater.compareAndSet(this, Status.ACTIVE, Status.ABORTED)) {
204           return true;
205         }
206       }
207       return this.getStatus() == Status.ABORTED;
208     } finally {
209       wakeUp();
210     }
211   }
212   
213   /**
214    * Returns a string representation of this transaction
215    * @return the string representcodes[ation
216    */
217   public String toString() {
218     switch (this.status) {
219       case COMMITTED:
220         return "Transaction" + this.startTime + "[committed]";
221       case ABORTED:
222         return "Transaction" + this.startTime + "[aborted]";
223       case ACTIVE:
224         return "Transaction" + this.startTime + "[active]";
225       default:
226         return "Transaction" + this.startTime + "[???]";
227     }
228   }
229   
230   /**
231    * Block caller while transaction is active.
232    */
233   public synchronized void waitWhileActive() {
234     while (this.getStatus() == Status.ACTIVE) {
235       try {
236         wait();
237       } catch (InterruptedException ex) {}
238     }
239   }
240   /**
241    * Block caller while transaction is active.
242    */
243   public synchronized void waitWhileActiveNotWaiting() {
244     while (getStatus() == Status.ACTIVE && !waiting) {
245       try {
246         wait();
247       } catch (InterruptedException ex) {}
248     }
249   }
250   
251   /**
252    * Wake up any transactions waiting for this one to finish.
253    */
254   public synchronized void wakeUp() {
255     notifyAll();
256   }
257   
258   /**
259    * This transaction's contention manager
260    * @return the manager
261    */
262   public ContentionManager getContentionManager() {
263     return manager;
264   }
265 }