*** empty log message ***
[IRC.git] / Robust / Transactions / dstm2 / src / dstm2 / AtomicByteArray.java
1 package dstm2;
2
3 /*
4  * AtomicArray.java
5  *
6  * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, Santa
7  * Clara, California 95054, U.S.A.  All rights reserved.  
8  * 
9  * Sun Microsystems, Inc. has intellectual property rights relating to
10  * technology embodied in the product that is described in this
11  * document.  In particular, and without limitation, these
12  * intellectual property rights may include one or more of the
13  * U.S. patents listed at http://www.sun.com/patents and one or more
14  * additional patents or pending patent applications in the U.S. and
15  * in other countries.
16  * 
17  * U.S. Government Rights - Commercial software.
18  * Government users are subject to the Sun Microsystems, Inc. standard
19  * license agreement and applicable provisions of the FAR and its
20  * supplements.  Use is subject to license terms.  Sun, Sun
21  * Microsystems, the Sun logo and Java are trademarks or registered
22  * trademarks of Sun Microsystems, Inc. in the U.S. and other
23  * countries.  
24  * 
25  * This product is covered and controlled by U.S. Export Control laws
26  * and may be subject to the export or import laws in other countries.
27  * Nuclear, missile, chemical biological weapons or nuclear maritime
28  * end uses or end users, whether direct or indirect, are strictly
29  * prohibited.  Export or reexport to countries subject to
30  * U.S. embargo or to entities identified on U.S. export exclusion
31  * lists, including, but not limited to, the denied persons and
32  * specially designated nationals lists is strictly prohibited.
33  */
34
35
36
37 import TransactionalIO.exceptions.AbortedException;
38 import TransactionalIO.exceptions.PanicException;
39 import dstm2.factory.ofree.ReadSet;
40 import java.lang.reflect.Array;
41
42 /**
43  * @author mph
44  */
45 @atomic public class AtomicByteArray {
46   
47   private final Byte[] array;
48   private final Byte[] shadow;
49   private Transaction writer;
50   private ReadSet readers;
51   long version;
52   private final String FORMAT = "Unexpected transaction state: %s";
53   
54   /** Creates a new instance of AtomicArray */
55   public AtomicByteArray(Class _class, int capacity) {
56     array  = (Byte[]) Array.newInstance(_class, capacity);
57     shadow = (Byte[]) Array.newInstance(_class, capacity);
58     writer = Transaction.COMMITTED;
59     readers = new ReadSet();
60     version = 0;
61   }
62   
63   public int length(){
64       return array.length;
65   }
66   
67   public Byte get(int i) {
68     Transaction me  = Thread.getTransaction();
69     Transaction other = null;
70     ContentionManager manager = Thread.getContentionManager();
71     while (true) {
72       synchronized (this) {
73         other = openRead(me);
74         if (other == null) {
75           return array[i];
76         }
77       }
78       manager.resolveConflict(me, other);
79     }
80   }
81   
82   public void set(int i, Byte value) {
83     Transaction me  = Thread.getTransaction();
84     Transaction other = null;
85     ContentionManager manager = Thread.getContentionManager();
86     while (true) {
87       synchronized (this) {
88         other = openWrite(me);
89         if (other == null) {
90           array[i] = value;
91           return;
92         }
93       }
94       manager.resolveConflict(me, other);
95     }
96   }
97   /**
98    * Tries to open object for reading. Returns reference to conflictin transaction, if one exists
99    **/
100   private Transaction openRead(Transaction me) {
101     // not in a transaction
102     if (me == null) {   // restore object if latest writer aborted
103       if (writer.isAborted()) {
104         restore();
105         version++;
106         writer = Transaction.COMMITTED;
107       }
108       return null;
109     }
110     // Am I still active?
111     if (!me.isActive()) {
112       throw new AbortedException();
113     }
114     // Have I already opened this object?
115     if (writer == me) {
116       return null;
117     }
118     switch (writer.getStatus()) {
119       case ACTIVE:
120         return writer;
121       case COMMITTED:
122         break;
123       case ABORTED:
124         restore();
125         version++;
126         break;
127       default:
128         throw new PanicException(FORMAT, writer.getStatus());
129     }
130     writer = Transaction.COMMITTED;
131     readers.add(me);
132     return null;
133   }
134   
135   /**
136    * Tries to open object for reading. Returns reference to conflicting transaction, if one exists
137    **/
138   public Transaction openWrite(Transaction me) {
139     // not in a transaction
140     if (me == null) {   // restore object if latest writer aborted
141       if (writer.isAborted()) {
142         restore();
143         version++;
144         writer = Transaction.COMMITTED;
145       }
146       return null;
147     }
148     if (!me.validate()) {
149       throw new AbortedException();
150     }
151     if (me == writer) {
152       return null;
153     }
154     for (Transaction reader : readers) {
155       if (reader.isActive() && reader != me) {
156         return reader;
157       }
158     }
159     readers.clear();
160     switch (writer.getStatus()) {
161       case ACTIVE:
162         return writer;
163       case COMMITTED:
164         backup();
165         version++;
166         break;
167       case ABORTED:
168         restore();
169         version++;
170         break;
171       default:
172         throw new PanicException(FORMAT, writer.getStatus());
173     }
174     writer = me;
175     return null;
176   }
177   
178   private void restore() {
179     System.arraycopy(shadow, 0, array, 0, array.length);
180   }
181   private void backup() {
182     System.arraycopy(array, 0, shadow, 0, array.length);
183   }
184   
185 }