factory additions
authornavid <navid>
Thu, 8 Jan 2009 01:07:30 +0000 (01:07 +0000)
committernavid <navid>
Thu, 8 Jan 2009 01:07:30 +0000 (01:07 +0000)
12 files changed:
Robust/Transactions/dstm2/src/dstm2/Init.java [new file with mode: 0644]
Robust/Transactions/dstm2/src/dstm2/Thread.java
Robust/Transactions/dstm2/src/dstm2/factory/ofree/Adapter.java [new file with mode: 0644]
Robust/Transactions/dstm2/src/dstm2/factory/ofree/CopyableFactory.java [new file with mode: 0644]
Robust/Transactions/dstm2/src/dstm2/factory/ofree/Locator.java [new file with mode: 0644]
Robust/Transactions/dstm2/src/dstm2/factory/ofree/Node.java [new file with mode: 0644]
Robust/Transactions/dstm2/src/dstm2/factory/ofree/ReadSet.java [new file with mode: 0644]
Robust/Transactions/dstm2/src/dstm2/factory/shadow/Adapter.java [new file with mode: 0644]
Robust/Transactions/dstm2/src/dstm2/factory/shadow/ReadSet.java [new file with mode: 0644]
Robust/Transactions/dstm2/src/dstm2/factory/shadow/Recoverable.java [new file with mode: 0644]
Robust/Transactions/dstm2/src/dstm2/factory/shadow/RecoverableFactory.java [new file with mode: 0644]
Robust/Transactions/dstm2/src/dstm2/factory/twophase/Adapter.java [new file with mode: 0644]

diff --git a/Robust/Transactions/dstm2/src/dstm2/Init.java b/Robust/Transactions/dstm2/src/dstm2/Init.java
new file mode 100644 (file)
index 0000000..b7a8791
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package dstm2;
+
+/**
+ *
+ * @author navid
+ */
+public class Init {
+
+    public static void init(){
+        String managerClassName = Defaults.MANAGER;
+        Class managerClass = null;
+        String adapterClassName = Defaults.ADAPTER;
+    
+    // discard statistics from previous runs
+    
+    // Parse and check the args
+    
+    // Initialize contention manager.
+    try {
+      managerClass = Class.forName(Defaults.MANAGER);
+      Thread.setContentionManagerClass(managerClass);
+    } catch (ClassNotFoundException ex) {
+      
+    }
+    
+    // Initialize adapter class
+      Thread.setAdapterClass(adapterClassName);
+      System.out.println(adapterClassName);
+    }
+}
index adf02fac6bc8a3e656691fe4fe2616fcb6325a85..c21a7c78eb0edc2afb7096892f29822300aec9f8 100644 (file)
@@ -245,17 +245,19 @@ public class Thread extends java.lang.Thread {
     ThreadState threadState = _threadState.get();
     ContentionManager manager = threadState.manager;
     T result = null;
+   // System.out.println(Thread.currentThread() + " astarted the transaction");
     boolean flag = false;
     try {
       while (true) {
         threadState.beginTransaction();
-
+     //   System.out.println(Thread.currentThread() + " offically started the transaction");
        /////For Integrating with IO////////// 
         Wrapper.Initialize(Thread.getTransaction());
+      //  System.out.println(Thread.currentThread() + " even more offically started the transaction");
        ////////////////////////////////////// 
         try {
           result = xaction.call();
-          
+      //     System.out.println(Thread.currentThread() + " aborted in committing");
       //  } catch (AbortedException d) {
           /*  synchronized(benchmark.lock){
                 System.out.println(Thread.currentThread() + " aborted in committing");
@@ -268,19 +270,11 @@ public class Thread extends java.lang.Thread {
       //    e.printStackTrace();
        //   throw new PanicException("Unhandled exception " + e);
        // }
-        threadState.totalMemRefs += threadState.transaction.memRefs;
-        threadState.transaction.attempts++;
-         /*synchronized(benchmark.lock){
-                    System.out.println(Thread.currentThread() + " ghabl az try");
-                }*/
-       // try{
-            
-                
-            //    if (!flag)
-                    Wrapper.prepareIOCommit();
-                /* synchronized(benchmark.lock){
-                    System.out.println(Thread.currentThread() + " to try");
-                }*/
+            threadState.totalMemRefs += threadState.transaction.memRefs;
+            threadState.transaction.attempts++;
+     
+            Wrapper.prepareIOCommit();
+
         ///////////////////////////////
         
                 if (threadState.commitTransaction()) {
@@ -292,10 +286,8 @@ public class Thread extends java.lang.Thread {
         }
         catch(AbortedException ex){
             threadState.depth--;
-         ///   synchronized(benchmark.lock){
-            //    System.out.println(Thread.currentThread() + " aborted in committing");
-            //}
-         
+          //  System.out.println("aborted");
+           // Wrapper.getTransaction().unlockAllLocks();
         }
         catch (Exception e) {
           e.printStackTrace();
@@ -303,6 +295,7 @@ public class Thread extends java.lang.Thread {
         }
         finally{
             
+            
             Wrapper.getTransaction().unlockAllLocks();
             if  (flag == true)
                 break;
@@ -325,7 +318,9 @@ public class Thread extends java.lang.Thread {
       totalTotal += threadState.total;
       threadState.reset();  // set up for next iteration
     }
-    throw new GracefulException();
+    if (result == null)
+        throw new GracefulException();
+    else return result;
   }
   /**
    * Execute transaction
diff --git a/Robust/Transactions/dstm2/src/dstm2/factory/ofree/Adapter.java b/Robust/Transactions/dstm2/src/dstm2/factory/ofree/Adapter.java
new file mode 100644 (file)
index 0000000..238e6c3
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * Adapter.java
+ *
+ * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, California 95054, U.S.A.  All rights reserved.  
+ * 
+ * Sun Microsystems, Inc. has intellectual property rights relating to
+ * technology embodied in the product that is described in this
+ * document.  In particular, and without limitation, these
+ * intellectual property rights may include one or more of the
+ * U.S. patents listed at http://www.sun.com/patents and one or more
+ * additional patents or pending patent applications in the U.S. and
+ * in other countries.
+ * 
+ * U.S. Government Rights - Commercial software.
+ * Government users are subject to the Sun Microsystems, Inc. standard
+ * license agreement and applicable provisions of the FAR and its
+ * supplements.  Use is subject to license terms.  Sun, Sun
+ * Microsystems, the Sun logo and Java are trademarks or registered
+ * trademarks of Sun Microsystems, Inc. in the U.S. and other
+ * countries.  
+ * 
+ * This product is covered and controlled by U.S. Export Control laws
+ * and may be subject to the export or import laws in other countries.
+ * Nuclear, missile, chemical biological weapons or nuclear maritime
+ * end uses or end users, whether direct or indirect, are strictly
+ * prohibited.  Export or reexport to countries subject to
+ * U.S. embargo or to entities identified on U.S. export exclusion
+ * lists, including, but not limited to, the denied persons and
+ * specially designated nationals lists is strictly prohibited.
+ */
+
+package dstm2.factory.ofree;
+import dstm2.ContentionManager;
+import dstm2.Transaction;
+import TransactionalIO.exceptions.AbortedException;
+import TransactionalIO.exceptions.PanicException;
+import TransactionalIO.exceptions.SnapshotException;
+import dstm2.factory.Copyable;
+import dstm2.factory.Factory;
+import dstm2.Thread;
+import dstm2.factory.Releasable;
+import dstm2.factory.Snapable;
+import dstm2.factory.ofree.CopyableFactory;
+import dstm2.factory.ofree.Locator;
+import dstm2.factory.shadow.RecoverableFactory;
+import java.lang.Class;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Obstruction-free atomic object implementation. Visible reads.
+ * Support snapshots and early release.
+ * @author Maurice Herlihy
+ */
+public class Adapter<T> implements dstm2.factory.Adapter<T>, Releasable, Snapable<T> {
+  protected Class<T> iface;
+  protected Factory<T> factory;
+  protected AtomicReference<Locator> start;
+  
+  /**
+   * Creates a new instance of Adapter
+   */
+  public Adapter(Class<T> _class) {
+    iface = _class;
+    factory = new CopyableFactory<T>(iface);
+    
+    Locator locator = new Locator(Transaction.COMMITTED, (Copyable)factory.create());
+    start = new AtomicReference<Locator>(locator);
+  }
+  
+  public <V> Adapter.Setter<V> makeSetter(String methodName, Class<V> _class) {
+    try {
+      T version = (T) start.get().newVersion;
+      final Method method = version.getClass().getMethod(methodName, _class);
+      return new Adapter.Setter<V>() {
+        public void call(V value) {
+          try {
+            Transaction me  = Thread.getTransaction();
+            Locator oldLocator = start.get();
+            T version = (T) oldLocator.fastPath(me);
+            if (version != null) {
+              method.invoke(version, value);
+              return;
+            }
+            ContentionManager manager = Thread.getContentionManager();
+            Locator newLocator = new Locator(me, (Copyable)factory.create());
+            version = (T) newLocator.newVersion;
+            while (true) {
+              oldLocator.writePath(me, manager, newLocator);
+              if (!me.isActive()) {
+                throw new AbortedException();
+              }
+              method.invoke(version, value);
+              if (Adapter.this.start.compareAndSet(oldLocator, newLocator)) {
+                return;
+              }
+              oldLocator = Adapter.this.start.get();
+            }
+          } catch (IllegalAccessException e) {
+            throw new PanicException(e);
+          } catch (InvocationTargetException e) {
+            throw new PanicException(e);
+          }
+        }};
+    } catch (NoSuchMethodException e) {
+      throw new PanicException(e);
+    }
+  }
+  
+  public <V> Adapter.Getter<V> makeGetter(String methodName, Class<V> _class)  {
+    try {
+      T version = (T) start.get().newVersion;
+      final Method method = version.getClass().getMethod(methodName);
+      return new Adapter.Getter<V>() {
+        public V call() {
+          try {
+            Transaction me  = Thread.getTransaction();
+            Locator oldLocator = Adapter.this.start.get();
+            T version = (T) oldLocator.fastPath(me);
+            if (version == null) {
+              ContentionManager manager = Thread.getContentionManager();
+              Locator newLocator = new Locator();
+              while (true) {
+                oldLocator.readPath(me, manager, newLocator);
+                if (Adapter.this.start.compareAndSet(oldLocator, newLocator)) {
+                  version = (T) newLocator.newVersion;
+                  break;
+                }
+                oldLocator = start.get();
+              }
+              if (!me.isActive()) {
+                throw new AbortedException();
+              }
+            }
+            return (V)method.invoke(version);
+          } catch (SecurityException e) {
+            throw new PanicException(e);
+          } catch (IllegalAccessException e) {
+            throw new PanicException(e);
+          } catch (InvocationTargetException e) {
+            throw new PanicException(e);
+          }
+        }};
+    } catch (NoSuchMethodException e) {
+      throw new PanicException(e);
+    }
+  }
+  
+  public void release() {
+    Transaction me  = Thread.getTransaction();
+    Locator oldLocator = this.start.get();
+    T version = (T) oldLocator.fastPath(me);
+    if (version == null) {
+      ContentionManager manager = Thread.getContentionManager();
+      Locator newLocator = new Locator();
+      version = (T) newLocator.newVersion;
+      while (true) {
+        oldLocator.releasePath(me, manager, newLocator);
+        if (this.start.compareAndSet(oldLocator, newLocator)) {
+          break;
+        }
+        oldLocator = this.start.get();
+      }
+      if (!me.isActive()) {
+        throw new AbortedException();
+      }
+    }
+    return;
+  }
+  
+  public T snapshot() {
+    Transaction me  = Thread.getTransaction();
+    Locator oldLocator = this.start.get();
+    T version = (T) oldLocator.fastPath(me);
+    if (version == null) {
+      ContentionManager manager = Thread.getContentionManager();
+      return (T)oldLocator.snapshot(me, manager);
+    } else {
+      return version;
+    }
+  }
+  
+  public void validate(T snap) {
+    if (snap != snapshot()) {
+      throw new SnapshotException();
+    }
+  }
+  
+  public void upgrade(T snap) {
+    Transaction me  = Thread.getTransaction();
+    Locator oldLocator = this.start.get();
+    T version = (T) oldLocator.fastPath(me);
+    if (version != null) {
+      if (version != snap) {
+        throw new SnapshotException();
+      } else {
+        return;
+      }
+    }
+    ContentionManager manager = Thread.getContentionManager();
+    Locator newLocator = new Locator(me, (Copyable)factory.create());
+    while (true) {
+      oldLocator.writePath(me, manager, newLocator);
+      if (!me.isActive()) {
+        throw new AbortedException();
+      }
+      if (snap != newLocator.oldVersion) {
+        throw new SnapshotException();
+      }
+      if (this.start.compareAndSet(oldLocator, newLocator)) {
+        return;
+      }
+      oldLocator = this.start.get();
+    }
+  }
+  
+}
+
diff --git a/Robust/Transactions/dstm2/src/dstm2/factory/ofree/CopyableFactory.java b/Robust/Transactions/dstm2/src/dstm2/factory/ofree/CopyableFactory.java
new file mode 100644 (file)
index 0000000..9dcc691
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * CopyableFactory.java
+ *
+ * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, California 95054, U.S.A.  All rights reserved.  
+ * 
+ * Sun Microsystems, Inc. has intellectual property rights relating to
+ * technology embodied in the product that is described in this
+ * document.  In particular, and without limitation, these
+ * intellectual property rights may include one or more of the
+ * U.S. patents listed at http://www.sun.com/patents and one or more
+ * additional patents or pending patent applications in the U.S. and
+ * in other countries.
+ * 
+ * U.S. Government Rights - Commercial software.
+ * Government users are subject to the Sun Microsystems, Inc. standard
+ * license agreement and applicable provisions of the FAR and its
+ * supplements.  Use is subject to license terms.  Sun, Sun
+ * Microsystems, the Sun logo and Java are trademarks or registered
+ * trademarks of Sun Microsystems, Inc. in the U.S. and other
+ * countries.  
+ * 
+ * This product is covered and controlled by U.S. Export Control laws
+ * and may be subject to the export or import laws in other countries.
+ * Nuclear, missile, chemical biological weapons or nuclear maritime
+ * end uses or end users, whether direct or indirect, are strictly
+ * prohibited.  Export or reexport to countries subject to
+ * U.S. embargo or to entities identified on U.S. export exclusion
+ * lists, including, but not limited to, the denied persons and
+ * specially designated nationals lists is strictly prohibited.
+ */
+
+package dstm2.factory.ofree;
+import TransactionalIO.exceptions.PanicException;
+import dstm2.Transaction;
+import dstm2.factory.BaseFactory;
+import dstm2.factory.ClassLoader;
+import dstm2.factory.Property;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import org.apache.bcel.Constants;
+import org.apache.bcel.classfile.Method;
+import org.apache.bcel.generic.*;
+
+/**
+ * @author Maurice Herlihy
+ */
+public class CopyableFactory<T> extends BaseFactory<T> {
+  
+/*
+ * CopyableFactory.java
+ *
+ * Created on November 21, 2005, 8:54 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+  
+  /**
+   * Creates a new instance of CopyableFactory
+   */
+  public CopyableFactory(Class<T> _class) {
+    super(_class);
+    synchronized(lock) {
+      className = _class.getName() + "$";
+      int constants = Constants.ACC_PUBLIC | Constants.ACC_SUPER;
+      String[] interfaces = new String[] {_class.getName(), "dstm2.factory.Copyable"};
+      _cg = new ClassGen(className, "java.lang.Object", null, constants, interfaces);
+      _cp = _cg.getConstantPool();
+      _factory = new InstructionFactory(_cg, _cp);
+      createCtor();
+      for (Property p : properties) {
+        createField(p.type, p.name);
+        createGetMethod(p);
+        createSetMethod(p);
+      }
+      createCopyFrom();
+      seal();
+    }
+  }
+  
+  /**
+   * Create an object.
+   * @return the object.
+   */
+  public T create() {
+    try {
+      synchronized (lock) {
+        return theClass.newInstance();
+      }
+    } catch (Exception ex) {
+      throw new PanicException(ex);
+    }
+  }
+  
+  private void createCtor() {
+    InstructionList il = new InstructionList();
+    MethodGen method = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, Type.NO_ARGS, new String[] {  }, "<init>", className, il, _cp);
+    
+    il.append(_factory.createLoad(Type.OBJECT, 0));
+    il.append(_factory.createInvoke("java.lang.Object", "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
+    il.append(_factory.createReturn(Type.VOID));
+    method.setMaxStack();
+    method.setMaxLocals();
+    _cg.addMethod(method.getMethod());
+    il.dispose();
+  }
+  private void createCopyFrom() {
+    InstructionList il = new InstructionList();
+    MethodGen method = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, new Type[] { Type.OBJECT }, new String[] { "arg0" }, "copyFrom", className, il, _cp);
+    
+    il.append(_factory.createLoad(Type.OBJECT, 1));
+    il.append(_factory.createCheckCast(new ObjectType(className)));
+    il.append(_factory.createStore(Type.OBJECT, 2));
+    for (Property p : properties) {
+      il.append(_factory.createLoad(Type.OBJECT, 0));
+      il.append(_factory.createLoad(Type.OBJECT, 2));
+      il.append(_factory.createFieldAccess(className, p.name, p.type, Constants.GETFIELD));
+      il.append(_factory.createFieldAccess(className, p.name, p.type, Constants.PUTFIELD));
+    }
+    il.append(_factory.createReturn(Type.VOID));
+    method.setMaxStack();
+    method.setMaxLocals();
+    _cg.addMethod(method.getMethod());
+    il.dispose();
+  }
+  
+  private void createGetMethod(Property p) {
+    InstructionList il = new InstructionList();
+    MethodGen method = new MethodGen(Constants.ACC_PUBLIC, p.type, Type.NO_ARGS, new String[] {  }, p.getMethod.getName(), className, il, _cp);
+    
+    il.append(_factory.createLoad(Type.OBJECT, 0));
+    il.append(_factory.createFieldAccess(className, p.name, p.type, Constants.GETFIELD));
+    il.append(_factory.createReturn(p.type));
+    method.setMaxStack();
+    method.setMaxLocals();
+    _cg.addMethod(method.getMethod());
+    il.dispose();
+  }
+  
+  private void createSetMethod(Property p) {
+    InstructionList il = new InstructionList();
+    MethodGen method = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, new Type[] { p.type }, new String[] { "value" }, p.setMethod.getName(), className, il, _cp);
+    
+    il.append(_factory.createLoad(Type.OBJECT, 0));
+    il.append(_factory.createLoad(p.type, 1));
+    il.append(_factory.createFieldAccess(className, p.name, p.type, Constants.PUTFIELD));
+    il.append(_factory.createReturn(Type.VOID));
+    method.setMaxStack();
+    method.setMaxLocals();
+    _cg.addMethod(method.getMethod());
+    il.dispose();
+  }
+  
+}
diff --git a/Robust/Transactions/dstm2/src/dstm2/factory/ofree/Locator.java b/Robust/Transactions/dstm2/src/dstm2/factory/ofree/Locator.java
new file mode 100644 (file)
index 0000000..eab24d0
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * Locator.java
+ *
+ * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, California 95054, U.S.A.  All rights reserved.  
+ * 
+ * Sun Microsystems, Inc. has intellectual property rights relating to
+ * technology embodied in the product that is described in this
+ * document.  In particular, and without limitation, these
+ * intellectual property rights may include one or more of the
+ * U.S. patents listed at http://www.sun.com/patents and one or more
+ * additional patents or pending patent applications in the U.S. and
+ * in other countries.
+ * 
+ * U.S. Government Rights - Commercial software.
+ * Government users are subject to the Sun Microsystems, Inc. standard
+ * license agreement and applicable provisions of the FAR and its
+ * supplements.  Use is subject to license terms.  Sun, Sun
+ * Microsystems, the Sun logo and Java are trademarks or registered
+ * trademarks of Sun Microsystems, Inc. in the U.S. and other
+ * countries.  
+ * 
+ * This product is covered and controlled by U.S. Export Control laws
+ * and may be subject to the export or import laws in other countries.
+ * Nuclear, missile, chemical biological weapons or nuclear maritime
+ * end uses or end users, whether direct or indirect, are strictly
+ * prohibited.  Export or reexport to countries subject to
+ * U.S. embargo or to entities identified on U.S. export exclusion
+ * lists, including, but not limited to, the denied persons and
+ * specially designated nationals lists is strictly prohibited.
+ */
+
+package dstm2.factory.ofree;
+import TransactionalIO.exceptions.AbortedException;
+import dstm2.ContentionManager;
+import TransactionalIO.exceptions.PanicException;
+import dstm2.Transaction.Status;
+import dstm2.Transaction;
+import dstm2.factory.Copyable;
+import dstm2.factory.SequentialFactory;
+import dstm2.factory.ofree.ReadSet;
+
+/**
+ * A locator points to an old version, a new version, and transactional
+ * bookkeeping information. A transaction opens an object by creating
+ * and installing a new locator.
+ *
+ * @author Maurice Herlihy
+ */
+public class Locator {
+  /**
+   * Transaction that last opened this object for writing.
+   */
+  public final Transaction writer;
+  /**
+   * Set of transactions currently reading this object.
+   */
+  public final ReadSet readers;
+  /**
+   * Prior version of object. Meaningless if last writer committed.
+   */
+  public volatile Copyable oldVersion;
+  /**
+   * Newer version of object. Tentative it writer is active, meaningless
+   * if writer is aborted, and otherwise the current value.
+   */
+  public volatile Copyable newVersion;
+  
+  /**
+   * Creates a new instance of Locator
+   * @param version Current version of object.
+   */
+  public Locator() {
+    writer = Transaction.COMMITTED;
+    readers = new ReadSet();
+    oldVersion = null;
+    newVersion = null;
+  }
+  /**
+   * Open object for writing.
+   * @param me Calling transaction.
+   * @param version Version to be modified.
+   */
+  public Locator(Transaction me, Copyable version) {
+    writer = me;
+    readers = new ReadSet(0);
+    oldVersion = null;
+    newVersion = version;
+  }
+  
+  /**
+   * Checks whether object is alread opened (for writing).
+   * @param me calling transaction
+   * @return Returns version if already open, null otherwise.
+   */
+  public Copyable fastPath(Transaction me) {
+    // not in a transaction, update in place
+    if (me == null) {
+      return getVersion(me, null);
+    } else if (writer == me) {  // already
+      return newVersion;
+    } else {
+      return null;
+    }
+  }
+  
+  public Copyable getVersion(Transaction me, ContentionManager manager) {
+    while (true) {
+      if (me != null && me.getStatus() == Status.ABORTED) {
+        throw new AbortedException();
+      }
+      switch (writer.getStatus()) {
+        case ACTIVE:
+          if (manager == null) {
+            throw new PanicException("Transactional/Non-Tranactional race");
+          }
+          manager.resolveConflict(me, writer);
+          continue;
+        case COMMITTED:
+          return newVersion;
+        case ABORTED:
+          return oldVersion;
+        default:
+          throw new PanicException("Unexpected transaction state: " + writer.getStatus());
+      }
+    }
+  }
+  
+  /**
+   * Prepare a new locator to be used to open object for reading.
+   * @param me calling transaction
+   * @param manager caller's contention manager
+   * @param newLocator Prepare this locator for reading the object.
+   */
+  public void readPath(Transaction me,
+      ContentionManager manager,
+      Locator newLocator) {
+    Copyable version = getVersion(me, manager);
+    newLocator.oldVersion = newLocator.newVersion = version;
+    newLocator.readers.copyFrom(readers);
+    newLocator.readers.add(me);
+    return;
+  }
+  
+  /**
+   * Prepare a new locator to be used to release prior read access.
+   * @param me calling transaction
+   * @param manager caller's contention manager
+   * @param newLocator Prepare this locator to replace current locator.
+   */
+  public void releasePath(Transaction me,
+      ContentionManager manager,
+      Locator newLocator) {
+    Copyable version = getVersion(me, manager);
+    newLocator.oldVersion = version;
+    newLocator.newVersion.copyFrom(version);
+    newLocator.readers.copyFrom(readers);
+    boolean present = newLocator.readers.remove(me);
+    if (!present) {
+      throw new PanicException("illegal release attempt");
+    }
+  }
+  
+  /**
+   * Prepare a new locator to be used to open object for writing.
+   * @param me caller
+   * @param manager caller's contention manager
+   * @param newLocator locator to prepare
+   */
+  public void writePath(Transaction me,
+      ContentionManager manager,
+      Locator newLocator) {
+    retry:
+      while (true) {
+        Copyable version = getVersion(me, manager);
+        newLocator.oldVersion = version;
+        newLocator.newVersion.copyFrom(version);
+        for (Transaction reader : readers) {
+          if (reader.isActive() && reader != me) {
+            manager.resolveConflict(me, readers);
+            continue retry;
+          }
+        }
+        return;
+      }
+  }
+  
+  public Copyable snapshot(Transaction me, ContentionManager manager) {
+    return getVersion(me, manager);
+  }
+}
diff --git a/Robust/Transactions/dstm2/src/dstm2/factory/ofree/Node.java b/Robust/Transactions/dstm2/src/dstm2/factory/ofree/Node.java
new file mode 100644 (file)
index 0000000..fd87e65
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Node.java
+ *
+ * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, California 95054, U.S.A.  All rights reserved.  
+ * 
+ * Sun Microsystems, Inc. has intellectual property rights relating to
+ * technology embodied in the product that is described in this
+ * document.  In particular, and without limitation, these
+ * intellectual property rights may include one or more of the
+ * U.S. patents listed at http://www.sun.com/patents and one or more
+ * additional patents or pending patent applications in the U.S. and
+ * in other countries.
+ * 
+ * U.S. Government Rights - Commercial software.
+ * Government users are subject to the Sun Microsystems, Inc. standard
+ * license agreement and applicable provisions of the FAR and its
+ * supplements.  Use is subject to license terms.  Sun, Sun
+ * Microsystems, the Sun logo and Java are trademarks or registered
+ * trademarks of Sun Microsystems, Inc. in the U.S. and other
+ * countries.  
+ * 
+ * This product is covered and controlled by U.S. Export Control laws
+ * and may be subject to the export or import laws in other countries.
+ * Nuclear, missile, chemical biological weapons or nuclear maritime
+ * end uses or end users, whether direct or indirect, are strictly
+ * prohibited.  Export or reexport to countries subject to
+ * U.S. embargo or to entities identified on U.S. export exclusion
+ * lists, including, but not limited to, the denied persons and
+ * specially designated nationals lists is strictly prohibited.
+ */
+
+package dstm2.factory.ofree;
+
+import dstm2.factory.Copyable;
+
+/**
+ *
+ * @author mph
+ */
+public class Node implements Copyable {
+  
+    private int value;
+    private Node next;
+  /** Creates a new instance of Node */
+  public Node() {
+  }
+
+  public int getValue() {
+    return value;
+  }
+
+  public void setValue(int value) {
+    this.value = value;
+  }
+
+  public void copyFrom(Copyable _other) {
+    Node other = (Node) _other;
+    value = other.value;
+    next = other.next;
+  }
+  
+}
diff --git a/Robust/Transactions/dstm2/src/dstm2/factory/ofree/ReadSet.java b/Robust/Transactions/dstm2/src/dstm2/factory/ofree/ReadSet.java
new file mode 100644 (file)
index 0000000..8c60985
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * ReadSet.java
+ *
+ * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, California 95054, U.S.A.  All rights reserved.  
+ * 
+ * Sun Microsystems, Inc. has intellectual property rights relating to
+ * technology embodied in the product that is described in this
+ * document.  In particular, and without limitation, these
+ * intellectual property rights may include one or more of the
+ * U.S. patents listed at http://www.sun.com/patents and one or more
+ * additional patents or pending patent applications in the U.S. and
+ * in other countries.
+ * 
+ * U.S. Government Rights - Commercial software.
+ * Government users are subject to the Sun Microsystems, Inc. standard
+ * license agreement and applicable provisions of the FAR and its
+ * supplements.  Use is subject to license terms.  Sun, Sun
+ * Microsystems, the Sun logo and Java are trademarks or registered
+ * trademarks of Sun Microsystems, Inc. in the U.S. and other
+ * countries.  
+ * 
+ * This product is covered and controlled by U.S. Export Control laws
+ * and may be subject to the export or import laws in other countries.
+ * Nuclear, missile, chemical biological weapons or nuclear maritime
+ * end uses or end users, whether direct or indirect, are strictly
+ * prohibited.  Export or reexport to countries subject to
+ * U.S. embargo or to entities identified on U.S. export exclusion
+ * lists, including, but not limited to, the denied persons and
+ * specially designated nationals lists is strictly prohibited.
+ */
+
+package dstm2.factory.ofree;
+
+import dstm2.Transaction;
+import dstm2.factory.ofree.ReadSet;
+import java.util.AbstractSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * ReadSet.java
+ * Keep track of transactions that opened this object for READ.
+ *
+ * @author Maurice Herlihy
+ */
+public class ReadSet extends AbstractSet<Transaction> {
+  
+  /**
+   * This value is public to facilitate unit testing.
+   */
+  public static int INITIAL_SIZE = 64;
+  /**
+   * Number of allocated slots. Must reallocate if actual number of
+   * transactions exceeds this size.
+   */
+  private int size;
+  /**
+   * Next free slot in array.
+   */
+  private int next;
+  /**
+   * Iterates over elements.
+   */
+  private Transaction elements[];
+  
+  /**
+   * Create ReadSet of default size.
+   */
+  public ReadSet() {
+    this(INITIAL_SIZE);
+  }
+  /**
+   * Create ReadSet of indicated size.
+   * @param size Size of readSet to create.
+   */
+  public ReadSet(int size) {
+    this.size = size;
+    elements = new Transaction[size];
+    next = 0;
+  }
+  
+  /**
+   * Initialize one object from another.
+   * @param aSet Initialize from this other object.
+   */
+  public void copyFrom(ReadSet aSet) {
+    if (aSet.size > this.size) {
+      elements = new Transaction[aSet.size];
+      this.size = aSet.size;
+    }
+    System.arraycopy(aSet.elements, 0, this.elements, 0, aSet.next);
+    this.next = aSet.next;
+  }
+  
+  /**
+   * Add a new transaction to the set.
+   * @param t Transaction to add.
+   * @return Whether this transaction was already present.
+   */
+  public boolean add(Transaction t) {
+    // try to reuse slot
+    for (int i = 0; i < next; i++) {
+      if (!elements[i].isActive()) {
+        elements[i] = t;
+        return true;
+      } else if (elements[i] == t) {
+        return true;
+      }
+    }
+    // check for overflow
+    if (next == size) {
+      Transaction[] newElements = new Transaction[2 * size];
+      System.arraycopy(elements, 0, newElements, 0, size);
+      elements = newElements;
+      size = 2 * size;
+    }
+    elements[next++] = t;
+    return true;
+  }
+  
+  /**
+   * remove transaction from the set.
+   * @param t Transaction to remove.
+   * @return Whether this transaction was already present.
+   */
+  public boolean remove(Transaction t) {
+    // try to reuse slot
+    int i = 0;
+    boolean present = false;
+    while(i < next) {
+      if (elements[i] == t) {
+        elements[i] = elements[next--];
+        present = true;
+      } else {
+        i++;
+      }
+    }
+    return present;
+  }
+  
+  /**
+   * Discard all elements of this set.
+   */
+  public void clear() {
+    next = 0;
+  }
+  
+  /**
+   * How many transactions in the set?
+   * @return Number of transactions in the set.
+   */
+  public int size() {
+    return next;
+  }
+  
+  /**
+   * Iterate over transaction in the set.
+   * @return Iterator over transactions in the set.
+   */
+  public java.util.Iterator<Transaction> iterator() {
+    return new Iterator();
+  }
+  
+  /**
+   * Inner class that implements iterator.
+   */
+  private class Iterator implements java.util.Iterator<Transaction> {
+    /**
+     * Iterator position.
+     */
+    int pos = 0;
+    /**
+     * Is there another transaction in the set?
+     * @return whether there are more active transactions
+     */
+    public boolean hasNext() {
+//      if (pos == next) {
+//        return false;
+//      }
+//      while (pos < next && !elements[pos].isActive()) {
+//        elements[pos] = elements[next-1]; // discard inactive transactions
+//        next--;
+//      }
+      return pos < next;
+    }
+    
+    /**
+     * Get next item in the set.
+     * @return next transaction in the set.
+     */
+    public Transaction next() {
+      return elements[pos++];
+    }
+    
+    /**
+     * Do not call this method.
+     */
+    public void remove() {
+      throw new java.lang.UnsupportedOperationException();
+    }
+  }
+}
diff --git a/Robust/Transactions/dstm2/src/dstm2/factory/shadow/Adapter.java b/Robust/Transactions/dstm2/src/dstm2/factory/shadow/Adapter.java
new file mode 100644 (file)
index 0000000..e080dc3
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Adapter.java
+ *
+ * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, California 95054, U.S.A.  All rights reserved.  
+ * 
+ * Sun Microsystems, Inc. has intellectual property rights relating to
+ * technology embodied in the product that is described in this
+ * document.  In particular, and without limitation, these
+ * intellectual property rights may include one or more of the
+ * U.S. patents listed at http://www.sun.com/patents and one or more
+ * additional patents or pending patent applications in the U.S. and
+ * in other countries.
+ * 
+ * U.S. Government Rights - Commercial software.
+ * Government users are subject to the Sun Microsystems, Inc. standard
+ * license agreement and applicable provisions of the FAR and its
+ * supplements.  Use is subject to license terms.  Sun, Sun
+ * Microsystems, the Sun logo and Java are trademarks or registered
+ * trademarks of Sun Microsystems, Inc. in the U.S. and other
+ * countries.  
+ * 
+ * This product is covered and controlled by U.S. Export Control laws
+ * and may be subject to the export or import laws in other countries.
+ * Nuclear, missile, chemical biological weapons or nuclear maritime
+ * end uses or end users, whether direct or indirect, are strictly
+ * prohibited.  Export or reexport to countries subject to
+ * U.S. embargo or to entities identified on U.S. export exclusion
+ * lists, including, but not limited to, the denied persons and
+ * specially designated nationals lists is strictly prohibited.
+ */
+
+package dstm2.factory.shadow;
+import dstm2.ContentionManager;
+import dstm2.Transaction;
+import TransactionalIO.exceptions.AbortedException;
+import TransactionalIO.exceptions.PanicException;
+import TransactionalIO.exceptions.SnapshotException;
+import dstm2.factory.Copyable;
+import dstm2.factory.Factory;
+import dstm2.Thread;
+import dstm2.factory.Releasable;
+import dstm2.factory.Snapable;
+import dstm2.factory.ofree.CopyableFactory;
+import dstm2.factory.ofree.Locator;
+import java.lang.Class;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Shadow-field atomic object implementation. Visible reads.
+ * Supports snapshots and early release.
+ * @author Maurice Herlihy
+ */
+public class Adapter<T> implements dstm2.factory.Adapter<T>, Releasable {
+  Class<T> iface;
+  T version;
+  Recoverable rVersion;
+  ContentionManager manager;
+  Transaction writer;
+  ReadSet readers;
+  private final String FORMAT = "Unexpected transaction state: %s";
+  /**
+   * A transaction switches to exclusive mode after being aborted this many times.
+   */
+  public static final int CONFLICT_THRESHOLD = 0;
+  
+  /**
+   * Creates a new instance of Adapter
+   */
+  public Adapter(Class<T> _class) {
+    iface = _class;
+    Factory<T> factory = new RecoverableFactory<T>(iface);
+    version = factory.create();
+    rVersion = (Recoverable)version;
+    manager = Thread.getContentionManager();
+    writer = Transaction.COMMITTED;
+    readers = new ReadSet();
+  }
+  
+  public <V> Adapter.Setter<V> makeSetter(String methodName, Class<V> _class) {
+    try {
+      final Method method = version.getClass().getMethod(methodName, _class);
+      return new Adapter.Setter<V>() {
+        public void call(V value) {
+          try {
+            Transaction me  = Thread.getTransaction();
+            Transaction other = null;
+            Set<Transaction> others = null;
+            while (true) {
+              synchronized (this) {
+                others = readWriteConflict(me);
+                if (others == null) {
+                  other = openWrite(me);
+                  if (other == null) {
+                    method.invoke(version, value);
+                    return;
+                  }
+                }
+              }
+              if (others != null) {
+                manager.resolveConflict(me, others);
+              } else if (other != null) {
+                manager.resolveConflict(me, other);
+              }
+            }
+          } catch (IllegalAccessException e) {
+            throw new PanicException(e);
+          } catch (InvocationTargetException e) {
+            throw new PanicException(e);
+          }
+        }};
+    } catch (NoSuchMethodException e) {
+      throw new PanicException(e);
+    }
+  }
+  
+  public <V> Adapter.Getter<V> makeGetter(String methodName, Class<V> _class)  {
+    try {
+      final Method method = version.getClass().getMethod(methodName);
+      return new Adapter.Getter<V>() {
+        public V call() {
+          try {
+            Transaction me  = Thread.getTransaction();
+            Transaction other = null;
+            while (true) {
+              synchronized (this) {
+                other = openRead(me);
+                //other = openWrite(me);
+                if (other == null) {
+                  return (V)method.invoke(version);
+                }
+              }
+              manager.resolveConflict(me, other);
+            }
+          } catch (SecurityException e) {
+            throw new PanicException(e);
+          } catch (IllegalAccessException e) {
+            throw new PanicException(e);
+          } catch (InvocationTargetException e) {
+            throw new PanicException(e);
+          }
+        }};
+    } catch (NoSuchMethodException e) {
+      throw new PanicException(e);
+    }
+  }
+  
+  public void release() {
+    Transaction me = Thread.getTransaction();
+    if (me != null) {
+      boolean ok = readers.remove(me);
+      if (!ok) {
+        throw new PanicException("illegal release attempt");
+      }
+    }
+  }
+  /**
+   * Tries to open object for reading. Returns reference to conflictin transaction, if one exists
+   **/
+  public Transaction openRead(Transaction me) {
+    // don't try read sharing if contention seems high
+    if (me == null) {  // restore object if latest writer aborted
+      if (writer.isAborted()) {
+        rVersion.recover();
+        writer = Transaction.COMMITTED;
+      }
+      return null;
+    }
+    if (me.attempts > CONFLICT_THRESHOLD) {
+      return openWrite(me);
+    }
+    // Am I still active?
+    if (!me.isActive()) {
+      throw new AbortedException();
+    }
+    // Have I already opened this object?
+    if (writer == me) {
+      return null;
+    }
+    switch (writer.getStatus()) {
+      case ACTIVE:
+        return writer;
+      case COMMITTED:
+        break;
+      case ABORTED:
+        rVersion.recover();
+        break;
+      default:
+        throw new PanicException(FORMAT, writer.getStatus());
+    }
+    writer = Transaction.COMMITTED;
+    readers.add(me);
+    manager.openSucceeded();
+    return null;
+  }
+  
+  /**
+   * Tries to open object for reading.
+   * Returns reference to conflicting transaction, if one exists
+   **/
+  Transaction openWrite(Transaction me) {
+    boolean cacheHit = false;  // already open for read?
+    // not in a transaction
+    if (me == null) {  // restore object if latest writer aborted
+      if (writer.isAborted()) {
+        rVersion.recover();
+        writer = Transaction.COMMITTED;
+      }
+      return null;
+    }
+    if (!me.isActive()) {
+      throw new AbortedException();
+    }
+    if (me == writer) {
+      return null;
+    }
+    switch (writer.getStatus()) {
+      case ACTIVE:
+        return writer;
+      case COMMITTED:
+        rVersion.backup();
+        break;
+      case ABORTED:
+        rVersion.recover();
+        break;
+      default:
+        throw new PanicException(FORMAT, writer.getStatus());
+    }
+    writer = me;
+    if (!cacheHit) {
+      me.memRefs++;
+      manager.openSucceeded();
+    }
+    return null;
+  }
+  
+  public Set<Transaction> readWriteConflict(Transaction me) {
+    for (Transaction reader : readers) {
+      if (reader.isActive() && reader != me) {
+        return readers;
+      }
+    }
+    readers.clear();
+    return null;
+  }
+  
+}
+
diff --git a/Robust/Transactions/dstm2/src/dstm2/factory/shadow/ReadSet.java b/Robust/Transactions/dstm2/src/dstm2/factory/shadow/ReadSet.java
new file mode 100644 (file)
index 0000000..7013652
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * ReadSet.java
+ *
+ * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, California 95054, U.S.A.  All rights reserved.  
+ * 
+ * Sun Microsystems, Inc. has intellectual property rights relating to
+ * technology embodied in the product that is described in this
+ * document.  In particular, and without limitation, these
+ * intellectual property rights may include one or more of the
+ * U.S. patents listed at http://www.sun.com/patents and one or more
+ * additional patents or pending patent applications in the U.S. and
+ * in other countries.
+ * 
+ * U.S. Government Rights - Commercial software.
+ * Government users are subject to the Sun Microsystems, Inc. standard
+ * license agreement and applicable provisions of the FAR and its
+ * supplements.  Use is subject to license terms.  Sun, Sun
+ * Microsystems, the Sun logo and Java are trademarks or registered
+ * trademarks of Sun Microsystems, Inc. in the U.S. and other
+ * countries.  
+ * 
+ * This product is covered and controlled by U.S. Export Control laws
+ * and may be subject to the export or import laws in other countries.
+ * Nuclear, missile, chemical biological weapons or nuclear maritime
+ * end uses or end users, whether direct or indirect, are strictly
+ * prohibited.  Export or reexport to countries subject to
+ * U.S. embargo or to entities identified on U.S. export exclusion
+ * lists, including, but not limited to, the denied persons and
+ * specially designated nationals lists is strictly prohibited.
+ */
+
+package dstm2.factory.shadow;
+
+import dstm2.Transaction;
+import TransactionalIO.exceptions.PanicException;
+import java.util.AbstractSet;
+
+class ReadSet extends AbstractSet<Transaction> {
+  
+  /**
+   * This value is public to facilitate unit testing.
+   */
+  final static int INITIAL_SIZE = 64;
+  /**
+   * Number of allocated slots. Must reallocate if actual number of
+   * transactions exceeds this size.
+   */
+  private int size;
+  /**
+   * Next free slot in array.
+   */
+  private int next;
+  /**
+   * Iterates over elements.
+   */
+  private Transaction elements[];
+  
+  /**
+   * Create ReadSet of default size.
+   */
+  public ReadSet() {
+    this(INITIAL_SIZE);
+  }
+  /**
+   * Create ReadSet of indicated size.
+   * @param size Size of readSet to create.
+   */
+  public ReadSet(int size) {
+    this.size = size;
+    elements = new Transaction[size];
+    next = 0;
+  }
+  
+  /**
+   * Initialize one object from another.
+   * @param aSet Initialize from this other object.
+   */
+  public void copyFrom(ReadSet aSet) {
+    if (aSet.size > this.size) {
+      elements = new Transaction[aSet.size];
+      this.size = aSet.size;
+    }
+    System.arraycopy(aSet.elements, 0, this.elements, 0, aSet.next);
+    this.next = aSet.next;
+  }
+  
+  /**
+   * Add a new transaction to the set.
+   * @param t Transaction to add.
+   * @return Whether this transaction was already present.
+   */
+  public boolean add(Transaction t) {
+    // try to reuse slot
+    for (int i = 0; i < next; i++) {
+      if (!elements[i].isActive()) {
+        elements[i] = t;
+        return true;
+      } else if (elements[i] == t) {
+        return true;
+      }
+    }
+    // check for overflow
+    if (next == size) {
+      Transaction[] newElements = new Transaction[2 * size];
+      System.arraycopy(elements, 0, newElements, 0, size);
+      elements = newElements;
+      size = 2 * size;
+    }
+    elements[next++] = t;
+    return true;
+  }
+  
+  /**
+   * remove transaction from the set.
+   * @param t Transaction to remove.
+   * @return Whether this transaction was already present.
+   */
+  public boolean remove(Transaction t) {
+    // try to reuse slot
+    int i = 0;
+    boolean present = false;
+    while(i < next) {
+      if (elements[i] == t) {
+        elements[i] = elements[next--];
+        present = true;
+      } else {
+        i++;
+      }
+    }
+    return present;
+  }
+  
+  /**
+   * Discard all elements of this set.
+   */
+  public void clear() {
+    next = 0;
+  }
+  
+  /**
+   * discard inactive transactions
+   * must be called only while object is locked!
+   **/
+//  public void clean() {
+//    int i = 0;
+//    while (i < next && (!elements[i].isActive())) {
+//      elements[i] = elements[next-1];
+//      next--;
+//    }
+//  }
+  /**
+   * How many transactions in the set?
+   * @return Number of transactions in the set.
+   */
+  public int size() {
+    return next;
+  }
+  
+  /**
+   * Iterate over transaction in the set.
+   * @return Iterator over transactions in the set.
+   */
+  public java.util.Iterator<Transaction> iterator() {
+    return new Iterator();
+  }
+  
+  /**
+   * Inner class that implements iterator.
+   */
+  private class Iterator implements java.util.Iterator<Transaction> {
+    /**
+     * Iterator position.
+     */
+    int pos = 0;
+    /**
+     * Is there another item in the set?
+     * @return whether there are more active transactions
+     */
+    public boolean hasNext() {
+      return pos < next;
+    }
+    
+    /**
+     * Get next item in the set.
+     * @return Next item in the set.
+     */
+    public Transaction next() {
+      return ReadSet.this.elements[pos++];
+    }
+    
+    /**
+     * Do not call this method.
+     */
+    public void remove() {
+      throw new java.lang.UnsupportedOperationException();
+    }
+  }
+}
diff --git a/Robust/Transactions/dstm2/src/dstm2/factory/shadow/Recoverable.java b/Robust/Transactions/dstm2/src/dstm2/factory/shadow/Recoverable.java
new file mode 100644 (file)
index 0000000..98bca43
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Recoverable.java
+ *
+ * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, California 95054, U.S.A.  All rights reserved.  
+ * 
+ * Sun Microsystems, Inc. has intellectual property rights relating to
+ * technology embodied in the product that is described in this
+ * document.  In particular, and without limitation, these
+ * intellectual property rights may include one or more of the
+ * U.S. patents listed at http://www.sun.com/patents and one or more
+ * additional patents or pending patent applications in the U.S. and
+ * in other countries.
+ * 
+ * U.S. Government Rights - Commercial software.
+ * Government users are subject to the Sun Microsystems, Inc. standard
+ * license agreement and applicable provisions of the FAR and its
+ * supplements.  Use is subject to license terms.  Sun, Sun
+ * Microsystems, the Sun logo and Java are trademarks or registered
+ * trademarks of Sun Microsystems, Inc. in the U.S. and other
+ * countries.  
+ * 
+ * This product is covered and controlled by U.S. Export Control laws
+ * and may be subject to the export or import laws in other countries.
+ * Nuclear, missile, chemical biological weapons or nuclear maritime
+ * end uses or end users, whether direct or indirect, are strictly
+ * prohibited.  Export or reexport to countries subject to
+ * U.S. embargo or to entities identified on U.S. export exclusion
+ * lists, including, but not limited to, the denied persons and
+ * specially designated nationals lists is strictly prohibited.
+ */
+
+package dstm2.factory.shadow;
+
+/**
+ * Interface for recoverable objects.
+ * @author Maurice Herlihy
+ */
+public interface Recoverable {
+  /**
+   * Copy fields to shadow fiels.
+   **/
+  void backup();
+  /**
+   * Copy shadow fields to fields.
+   **/
+  void recover();
+  
+}
diff --git a/Robust/Transactions/dstm2/src/dstm2/factory/shadow/RecoverableFactory.java b/Robust/Transactions/dstm2/src/dstm2/factory/shadow/RecoverableFactory.java
new file mode 100644 (file)
index 0000000..6083bed
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * RecoverableFactory.java
+ *
+ * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, California 95054, U.S.A.  All rights reserved.  
+ * 
+ * Sun Microsystems, Inc. has intellectual property rights relating to
+ * technology embodied in the product that is described in this
+ * document.  In particular, and without limitation, these
+ * intellectual property rights may include one or more of the
+ * U.S. patents listed at http://www.sun.com/patents and one or more
+ * additional patents or pending patent applications in the U.S. and
+ * in other countries.
+ * 
+ * U.S. Government Rights - Commercial software.
+ * Government users are subject to the Sun Microsystems, Inc. standard
+ * license agreement and applicable provisions of the FAR and its
+ * supplements.  Use is subject to license terms.  Sun, Sun
+ * Microsystems, the Sun logo and Java are trademarks or registered
+ * trademarks of Sun Microsystems, Inc. in the U.S. and other
+ * countries.  
+ * 
+ * This product is covered and controlled by U.S. Export Control laws
+ * and may be subject to the export or import laws in other countries.
+ * Nuclear, missile, chemical biological weapons or nuclear maritime
+ * end uses or end users, whether direct or indirect, are strictly
+ * prohibited.  Export or reexport to countries subject to
+ * U.S. embargo or to entities identified on U.S. export exclusion
+ * lists, including, but not limited to, the denied persons and
+ * specially designated nationals lists is strictly prohibited.
+ */
+
+package dstm2.factory.shadow;
+
+
+import dstm2.ContentionManager;
+import TransactionalIO.exceptions.AbortedException;
+import TransactionalIO.exceptions.PanicException;
+import dstm2.Transaction;
+import dstm2.Transaction.Status;
+import dstm2.factory.BaseFactory;
+import dstm2.factory.ClassLoader;
+import dstm2.factory.Copyable;
+import dstm2.factory.Property;
+import dstm2.factory.Snapable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import org.apache.bcel.Constants;
+import org.apache.bcel.classfile.Method;
+import org.apache.bcel.generic.*;
+
+import static org.apache.bcel.Constants.*;
+
+/**
+ * Implements simple object with getters and setters. Also provides a
+ * <code>copyTo</code> method that copies one such object to another.
+ * @author Maurice Herlihy
+ */
+public class RecoverableFactory<T> extends BaseFactory<T> {
+  public RecoverableFactory(Class<T> _class) {
+    super(_class);
+    synchronized (lock) {
+      className = _class.getName() + "$";
+      int constants = Constants.ACC_PUBLIC | Constants.ACC_SUPER;
+      String[] interfaces = new String[] {_class.getName(), "dstm2.factory.shadow.Recoverable"};
+      _cg = new ClassGen(className, "java.lang.Object", null, constants, interfaces);
+      _cp = _cg.getConstantPool();
+      _factory = new InstructionFactory(_cg, _cp);
+      createCtor();
+      for (Property p : properties) {
+        createField(p.type, p.name);        // actual field
+        createField(p.type, p.name + "$");  // shadow field
+        createGetMethod(p);
+        createSetMethod(p);
+      }
+      createBackup();
+      createRecover();
+      seal();
+    }
+  }
+  
+  /**
+   * Create an object.
+   * @return the object.
+   */
+  public T create() {
+    try {
+      synchronized (lock) {
+        return theClass.newInstance();
+      }
+    } catch (Exception ex) {
+      throw new PanicException(ex);
+    }
+  }
+  
+  private void createCtor() {
+    InstructionList il = new InstructionList();
+    MethodGen method = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, Type.NO_ARGS, new String[] {  }, "<init>", className, il, _cp);
+    
+    InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0));
+    il.append(_factory.createInvoke("java.lang.Object", "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
+    InstructionHandle ih_4 = il.append(_factory.createReturn(Type.VOID));
+    method.setMaxStack();
+    method.setMaxLocals();
+    _cg.addMethod(method.getMethod());
+    il.dispose();
+  }
+  public void createBackup() {
+    InstructionList il = new InstructionList();
+    MethodGen method = new MethodGen(ACC_PUBLIC, Type.VOID, Type.NO_ARGS, new String[] {  }, "backup", className, il, _cp);
+    
+    for (Property p : properties) {
+      InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0));
+      il.append(_factory.createLoad(Type.OBJECT, 0));
+      il.append(_factory.createFieldAccess(className, p.name, p.type, Constants.GETFIELD));
+      il.append(_factory.createFieldAccess(className, p.name + "$", p.type, Constants.PUTFIELD));
+    }
+    
+    InstructionHandle ih_24 = il.append(_factory.createReturn(Type.VOID));
+    method.setMaxStack();
+    method.setMaxLocals();
+    _cg.addMethod(method.getMethod());
+    il.dispose();
+  }
+  
+  public void createRecover() {
+    InstructionList il = new InstructionList();
+    MethodGen method = new MethodGen(ACC_PUBLIC, Type.VOID, Type.NO_ARGS, new String[] {  }, "recover", className, il, _cp);
+    
+    for (Property p : properties) {
+      InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0));
+      il.append(_factory.createLoad(Type.OBJECT, 0));
+      il.append(_factory.createFieldAccess(className, p.name + "$", p.type, Constants.GETFIELD));
+      il.append(_factory.createFieldAccess(className, p.name, p.type, Constants.PUTFIELD));
+    }
+    InstructionHandle ih_24 = il.append(_factory.createReturn(Type.VOID));
+    method.setMaxStack();
+    method.setMaxLocals();
+    _cg.addMethod(method.getMethod());
+    il.dispose();
+  }
+  
+  private void createGetMethod(Property p) {
+    InstructionList il = new InstructionList();
+    MethodGen method = new MethodGen(Constants.ACC_PUBLIC, p.type, Type.NO_ARGS, new String[] {  }, p.getMethod.getName(), className, il, _cp);
+    
+    InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0));
+    il.append(_factory.createFieldAccess(className, p.name, p.type, Constants.GETFIELD));
+    InstructionHandle ih_4 = il.append(_factory.createReturn(p.type));
+    method.setMaxStack();
+    method.setMaxLocals();
+    _cg.addMethod(method.getMethod());
+    il.dispose();
+  }
+  
+  private void createSetMethod(Property p) {
+    InstructionList il = new InstructionList();
+    MethodGen method = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, new Type[] { p.type }, new String[] { "value" }, p.setMethod.getName(), className, il, _cp);
+    
+    InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0));
+    il.append(_factory.createLoad(p.type, 1));
+    il.append(_factory.createFieldAccess(className, p.name, p.type, Constants.PUTFIELD));
+    InstructionHandle ih_5 = il.append(_factory.createReturn(Type.VOID));
+    method.setMaxStack();
+    method.setMaxLocals();
+    _cg.addMethod(method.getMethod());
+    il.dispose();
+  }
+}
diff --git a/Robust/Transactions/dstm2/src/dstm2/factory/twophase/Adapter.java b/Robust/Transactions/dstm2/src/dstm2/factory/twophase/Adapter.java
new file mode 100644 (file)
index 0000000..f8d8f11
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Adapter.java
+ *
+ * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, California 95054, U.S.A.  All rights reserved.  
+ * 
+ * Sun Microsystems, Inc. has intellectual property rights relating to
+ * technology embodied in the product that is described in this
+ * document.  In particular, and without limitation, these
+ * intellectual property rights may include one or more of the
+ * U.S. patents listed at http://www.sun.com/patents and one or more
+ * additional patents or pending patent applications in the U.S. and
+ * in other countries.
+ * 
+ * U.S. Government Rights - Commercial software.
+ * Government users are subject to the Sun Microsystems, Inc. standard
+ * license agreement and applicable provisions of the FAR and its
+ * supplements.  Use is subject to license terms.  Sun, Sun
+ * Microsystems, the Sun logo and Java are trademarks or registered
+ * trademarks of Sun Microsystems, Inc. in the U.S. and other
+ * countries.  
+ * 
+ * This product is covered and controlled by U.S. Export Control laws
+ * and may be subject to the export or import laws in other countries.
+ * Nuclear, missile, chemical biological weapons or nuclear maritime
+ * end uses or end users, whether direct or indirect, are strictly
+ * prohibited.  Export or reexport to countries subject to
+ * U.S. embargo or to entities identified on U.S. export exclusion
+ * lists, including, but not limited to, the denied persons and
+ * specially designated nationals lists is strictly prohibited.
+ */
+
+package dstm2.factory.twophase;
+import dstm2.ContentionManager;
+import dstm2.Transaction;
+import TransactionalIO.exceptions.AbortedException;
+import TransactionalIO.exceptions.PanicException;
+import TransactionalIO.exceptions.SnapshotException;
+import dstm2.factory.Factory;
+import dstm2.Thread;
+import dstm2.factory.shadow.Recoverable;
+import dstm2.factory.shadow.RecoverableFactory;
+import java.lang.Class;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Simple two-phase locking implementation.
+ * @author Maurice Herlihy
+ */
+public class Adapter<T> implements dstm2.factory.Adapter<T> {
+  T version;
+  Lock lock;
+  boolean firstTime;
+  private final String FORMAT = "Unexpected transaction state: %s";
+  private static Map<Class,Factory> map = new HashMap<Class,Factory>();
+  
+  /**
+   * Creates a new instance of Adapter
+   */
+  public Adapter(Class<T> _class) {
+    lock = new ReentrantLock();
+    Factory<T> factory = map.get(_class);
+    if (factory == null) {
+      factory = new RecoverableFactory(_class);
+      map.put(_class, factory);
+    }
+    version = factory.create();
+    firstTime = true;
+  }
+  
+  public <V> Adapter.Getter<V> makeGetter(String methodName, Class<V> _class)  {
+    try {
+      final Method method = version.getClass().getMethod(methodName);
+      return new Adapter.Getter<V>() {
+        public V call() {
+          try{
+            lock.lock();
+            if (firstTime) {
+              ((Recoverable)version).backup();
+              firstTime = false;
+            }
+    Thread.onCommitOnce( new Runnable() {
+      public void run() {
+        lock.unlock();
+      }
+    });
+    Thread.onAbortOnce( new Runnable() {
+      public void run() {
+        lock.unlock();
+        ((Recoverable)version).recover();
+      }
+    });
+            return (V)method.invoke(version);
+          } catch (IllegalArgumentException ex) {
+            throw new PanicException(ex);
+          } catch (IllegalAccessException ex) {
+            throw new PanicException(ex);
+          } catch (InvocationTargetException ex) {
+            throw new PanicException(ex);
+          }
+        }};
+    } catch (NoSuchMethodException e) {
+      throw new PanicException(e);
+    }
+  }
+  
+  public <V> Adapter.Setter<V> makeSetter(String methodName, Class<V> _class)  {
+    try {
+      final Method method = version.getClass().getMethod(methodName, _class);
+      return new Adapter.Setter<V>() {
+        public void call(V value) {
+          try{
+            lock.lock();
+            if (firstTime) {
+              ((Recoverable)version).backup();
+              firstTime = false;
+            }
+    Thread.onCommitOnce( new Runnable() {
+      public void run() {
+        lock.unlock();
+      }
+    });
+    Thread.onAbortOnce( new Runnable() {
+      public void run() {
+        lock.unlock();
+        ((Recoverable)version).recover();
+      }
+    });
+            method.invoke(version, value);
+          } catch (IllegalArgumentException ex) {
+            throw new PanicException(ex);
+          } catch (IllegalAccessException ex) {
+            throw new PanicException(ex);
+          } catch (InvocationTargetException ex) {
+            throw new PanicException(ex);
+          }
+        }};
+    } catch (NoSuchMethodException e) {
+      throw new PanicException(e);
+    }
+  }
+}
+