summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-07-31 13:42:46 +0000
committerRich Hickey <richhickey@gmail.com>2007-07-31 13:42:46 +0000
commitfaa1146288b03e82451943a3f7fd6e927bb1acc7 (patch)
treec1ec9cfb7359e53137d1dd36defb017a6a4be5bc /src
parent389cf13600985156e8e44640e2781d48af8e00a1 (diff)
removed dynamic binding from Refs
Diffstat (limited to 'src')
-rw-r--r--src/jvm/clojure/lang/Binding.java15
-rw-r--r--src/jvm/clojure/lang/DynamicVar.java72
-rw-r--r--src/jvm/clojure/lang/LockingTransaction.java4
-rw-r--r--src/jvm/clojure/lang/Ref.java50
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();