diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-07-31 13:42:46 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-07-31 13:42:46 +0000 |
commit | faa1146288b03e82451943a3f7fd6e927bb1acc7 (patch) | |
tree | c1ec9cfb7359e53137d1dd36defb017a6a4be5bc /src | |
parent | 389cf13600985156e8e44640e2781d48af8e00a1 (diff) |
removed dynamic binding from Refs
Diffstat (limited to 'src')
-rw-r--r-- | src/jvm/clojure/lang/Binding.java | 15 | ||||
-rw-r--r-- | src/jvm/clojure/lang/DynamicVar.java | 72 | ||||
-rw-r--r-- | src/jvm/clojure/lang/LockingTransaction.java | 4 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Ref.java | 50 |
4 files changed, 83 insertions, 58 deletions
diff --git a/src/jvm/clojure/lang/Binding.java b/src/jvm/clojure/lang/Binding.java index 9b8cae7b..f36c78d3 100644 --- a/src/jvm/clojure/lang/Binding.java +++ b/src/jvm/clojure/lang/Binding.java @@ -10,16 +10,17 @@ package clojure.lang;
-public class Binding {
+public class Binding{
public Object val;
-public Binding rest;
+public final Binding rest;
-public Binding(Object val) {
- this.val = val;
+public Binding(Object val){
+ this.val = val;
+ this.rest = null;
}
-public Binding(Object val, Binding rest) {
- this.val = val;
- this.rest = rest;
+public Binding(Object val, Binding rest){
+ this.val = val;
+ this.rest = rest;
}
}
diff --git a/src/jvm/clojure/lang/DynamicVar.java b/src/jvm/clojure/lang/DynamicVar.java new file mode 100644 index 00000000..d9ffad79 --- /dev/null +++ b/src/jvm/clojure/lang/DynamicVar.java @@ -0,0 +1,72 @@ +/** + * Copyright (c) Rich Hickey. All rights reserved. + * The use and distribution terms for this software are covered by the + * Common Public License 1.0 (http://opensource.org/licenses/cpl.php) + * which can be found in the file CPL.TXT at the root of this distribution. + * By using this software in any fashion, you are agreeing to be bound by + * the terms of this license. + * You must not remove this notice, or any other, from this software. + **/ + +/* rich Jul 31, 2007 */ + +package clojure.lang; + +public class DynamicVar{ +final InheritableThreadLocal<Binding> dvals; +Object root; + +public DynamicVar(){ + this.dvals = new InheritableThreadLocal<Binding>(); + this.root = dvals; //use dvals as magic not-bound value +} + +public DynamicVar(Object root){ + this(); + this.root = root; +} + +boolean isBound(){ + return root != dvals || dvals.get() != null; +} + +public Object get() throws Exception{ + Binding b = getThreadBinding(); + if(b != null) + return b.val; + if(root != dvals) + return root; + throw new IllegalStateException("Var is unbound."); +} + +public Object set(Object val) throws Exception{ + Binding b = getThreadBinding(); + if(b != null) + return (b.val = val); + throw new IllegalStateException("Var is unbound."); +} + +public Object getRoot(){ + return root; +} + +public void setRoot(Object root){ + this.root = root; +} + +public void pushThreadBinding(Object val){ + dvals.set(new Binding(val, dvals.get())); +} + +public void popThreadBinding() throws Exception{ + Binding b = dvals.get(); + if(b == null) + throw new Exception("Can't pop unbound ref"); + dvals.set(b.rest); +} + +final Binding getThreadBinding(){ + return dvals.get(); +} + +} diff --git a/src/jvm/clojure/lang/LockingTransaction.java b/src/jvm/clojure/lang/LockingTransaction.java index 5a20109d..8ee7678d 100644 --- a/src/jvm/clojure/lang/LockingTransaction.java +++ b/src/jvm/clojure/lang/LockingTransaction.java @@ -461,8 +461,8 @@ public static void main(String[] args){ si = (ArrayList<Ref>) items.clone(); } Collections.shuffle(si); - //tasks.add(new Incrementer(niters, si)); - tasks.add(new Commuter(niters, si)); + tasks.add(new Incrementer(niters, si)); + //tasks.add(new Commuter(niters, si)); } ExecutorService e = Executors.newFixedThreadPool(nthreads); diff --git a/src/jvm/clojure/lang/Ref.java b/src/jvm/clojure/lang/Ref.java index 8cdee3f6..9488da06 100644 --- a/src/jvm/clojure/lang/Ref.java +++ b/src/jvm/clojure/lang/Ref.java @@ -52,7 +52,6 @@ public static class TVal{ TVal tvals; final AtomicInteger faults; -transient volatile InheritableThreadLocal<Binding> dvals; final ReentrantReadWriteLock lock; LockingTransaction.Info tinfo; final UUID uuid; @@ -60,7 +59,6 @@ transient volatile Object cacheVal; public Ref(){ this.tvals = null; - this.dvals = null; this.tinfo = null; this.faults = new AtomicInteger(); this.lock = new ReentrantReadWriteLock(); @@ -78,7 +76,6 @@ public Ref(Object initVal){ //use only with a cache/registry public Ref(UUID uuid, Object initVal){ tvals = new TVal(initVal, 0, System.currentTimeMillis()); - this.dvals = null; this.tinfo = null; this.faults = new AtomicInteger(); this.lock = new ReentrantReadWriteLock(); @@ -94,9 +91,6 @@ public UUID getUUID(){ // ok out of transaction public Object cachedVal(){ - Binding b = getThreadBinding(); - if(b != null) - return b.val; if(cacheVal != lock) return cacheVal; try @@ -116,9 +110,6 @@ public Object cachedVal(){ // ok out of transaction public Object currentVal(){ - Binding b = getThreadBinding(); - if(b != null) - return b.val; try { lock.readLock().lock(); @@ -132,66 +123,27 @@ public Object currentVal(){ } } - -final Binding getThreadBinding(){ - if(dvals != null) - return dvals.get(); - return null; -} - -public void pushThreadBinding(Object val){ - if(dvals == null) - { - synchronized(this) - { - if(dvals == null) - dvals = new InheritableThreadLocal(); - } - } - dvals.set(new Binding(val, dvals.get())); -} - -public void popThreadBinding() throws Exception{ - Binding b; - if(dvals == null || (b = dvals.get()) == null) - throw new Exception("Can't pop unbound ref"); - dvals.set(b.rest); -} - //* //must be dynamically bound or transactional read public Object get() throws Exception{ - Binding b = getThreadBinding(); - if(b != null) - return b.val; return cacheVal = LockingTransaction.getEx().doGet(this); } public Object set(Object val) throws Exception{ - Binding b = getThreadBinding(); - if(b != null) - return (b.val = val); return LockingTransaction.getEx().doSet(this, val); } public Object commute(IFn fn) throws Exception{ - Binding b = getThreadBinding(); - if(b != null) - return (b.val = fn.invoke(b.val)); return LockingTransaction.getEx().doCommute(this, fn); } public void touch() throws Exception{ - Binding b = getThreadBinding(); - if(b == null) - LockingTransaction.getEx().doTouch(this); + LockingTransaction.getEx().doTouch(this); } //*/ boolean isBound(){ - if(dvals != null && dvals.get() != null) - return true; try { lock.readLock().lock(); |