diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-07-27 15:19:46 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-07-27 15:19:46 +0000 |
commit | 4294c94279eecee549d4969e194a40b5ea50649f (patch) | |
tree | 1dfdf7a2049c03ee6ff9288dafe81a924aac0682 /src | |
parent | 1ae93cc079b2a8c34537b576abb6a4f3cd302a9f (diff) |
lock based STM
Diffstat (limited to 'src')
-rw-r--r-- | src/jvm/clojure/lang/LockingTransaction.java | 39 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Ref.java | 14 |
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); } |