--- /dev/null
+/*
+ * 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);
+ }
+}
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");
// 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()) {
}
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();
}
finally{
+
Wrapper.getTransaction().unlockAllLocks();
if (flag == true)
break;
totalTotal += threadState.total;
threadState.reset(); // set up for next iteration
}
- throw new GracefulException();
+ if (result == null)
+ throw new GracefulException();
+ else return result;
}
/**
* Execute transaction
--- /dev/null
+/*
+ * 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();
+ }
+ }
+
+}
+
--- /dev/null
+/*
+ * 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();
+ }
+
+}
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+
+}
--- /dev/null
+/*
+ * 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();
+ }
+ }
+}
--- /dev/null
+/*
+ * 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;
+ }
+
+}
+
--- /dev/null
+/*
+ * 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();
+ }
+ }
+}
--- /dev/null
+/*
+ * 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();
+
+}
--- /dev/null
+/*
+ * 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();
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
+