summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-07-27 15:19:46 +0000
committerRich Hickey <richhickey@gmail.com>2007-07-27 15:19:46 +0000
commit4294c94279eecee549d4969e194a40b5ea50649f (patch)
tree1dfdf7a2049c03ee6ff9288dafe81a924aac0682 /src
parent1ae93cc079b2a8c34537b576abb6a4f3cd302a9f (diff)
lock based STM
Diffstat (limited to 'src')
-rw-r--r--src/jvm/clojure/lang/LockingTransaction.java39
-rw-r--r--src/jvm/clojure/lang/Ref.java14
2 files changed, 36 insertions, 17 deletions
diff --git a/src/jvm/clojure/lang/LockingTransaction.java b/src/jvm/clojure/lang/LockingTransaction.java
index 50fd628d..a0ae1c88 100644
--- a/src/jvm/clojure/lang/LockingTransaction.java
+++ b/src/jvm/clojure/lang/LockingTransaction.java
@@ -30,7 +30,7 @@ static class AbortException extends Exception{
//total order on transactions
//transactions will consume a point for init, for each retry, and on commit if writing
-private static long lastPoint = 0;
+private static long lastPoint;
final static PriorityQueue<Long> points = new PriorityQueue<Long>();
@@ -76,7 +76,7 @@ void stop(){
}
-Ref.TStatus tstatus;
+volatile Ref.TStatus tstatus;
long completedPriorPoint;
long readPoint;
HashMap<Ref, Object> vals = new HashMap<Ref, Object>();
@@ -300,6 +300,7 @@ Object doCommute(Ref ref, IFn fn) throws Exception{
//for test
static CyclicBarrier barrier;
+static ArrayList<Ref> items;
public static void main(String[] args){
try
@@ -311,10 +312,13 @@ public static void main(String[] args){
int niters = Integer.parseInt(args[2]);
int ninstances = Integer.parseInt(args[3]);
- final ArrayList<Ref> items = new ArrayList(nitems);
- for(int i = 0; i < nitems; i++)
- items.add(new Ref(0));
-
+ if(items == null)
+ {
+ ArrayList<Ref> temp = new ArrayList(nitems);
+ for(int i = 0; i < nitems; i++)
+ temp.add(new Ref(0));
+ items = temp;
+ }
class Incr extends AFn{
public Object invoke(Object arg1) throws Exception{
@@ -345,7 +349,7 @@ public static void main(String[] args){
for(int i = 0; i < niters; i++)
{
long start = System.nanoTime();
- Transaction.runInTransaction(this);
+ LockingTransaction.runInTransaction(this);
long dur = System.nanoTime() - start;
nanos += dur;
}
@@ -408,31 +412,44 @@ public static void main(String[] args){
ArrayList<Callable<Long>> tasks = new ArrayList(nthreads);
for(int i = 0; i < nthreads; i++)
{
- ArrayList<Ref> si = (ArrayList<Ref>) items.clone();
+ ArrayList<Ref> si;
+ synchronized(items)
+ {
+ si = (ArrayList<Ref>) items.clone();
+ }
Collections.shuffle(si);
tasks.add(new Incrementer(niters, si));
+ //tasks.add(new Commuter(niters, si));
}
ExecutorService e = Executors.newFixedThreadPool(nthreads);
if(barrier == null)
barrier = new CyclicBarrier(ninstances);
+ System.out.println("waiting for other instances...");
barrier.await();
+ System.out.println("starting");
long start = System.nanoTime();
List<Future<Long>> results = e.invokeAll(tasks);
long estimatedTime = System.nanoTime() - start;
System.out.printf("nthreads: %d, nitems: %d, niters: %d, time: %d%n", nthreads, nitems, niters,
estimatedTime / 1000000);
e.shutdown();
- barrier.await();
for(Future<Long> res : results)
{
System.out.printf("%d, ", res.get() / 1000000);
}
System.out.println();
- for(Ref item : items)
+ System.out.println("waiting for other instances...");
+ barrier.await();
+ synchronized(items)
{
- System.out.printf("%d, ", (Integer) item.currentVal());
+ for(Ref item : items)
+ {
+ System.out.printf("%d, ", (Integer) item.currentVal());
+ }
}
+ System.out.println("\ndone");
+ System.out.flush();
}
catch(Exception ex)
{
diff --git a/src/jvm/clojure/lang/Ref.java b/src/jvm/clojure/lang/Ref.java
index 1a2f0153..7e7d29d1 100644
--- a/src/jvm/clojure/lang/Ref.java
+++ b/src/jvm/clojure/lang/Ref.java
@@ -16,7 +16,14 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-public class Ref implements IFn{
+public class Ref implements IFn, Comparable<Ref>{
+public int compareTo(Ref o){
+ if(o.id == id)
+ return 0;
+ if(o.id > id)
+ return -1;
+ return 1;
+}
public static class TVal{
final Object val;
@@ -115,11 +122,6 @@ public Object set(Object val) throws Exception{
Binding b = getThreadBinding();
if(b != null)
return (b.val = val);
- //allow out-of-transaction inits via set??
- if(!isBound())
- {
- //no
- }
return LockingTransaction.getEx().doSet(this, val);
}