Skip to content

Commit 04bd305

Browse files
committed
Explorations in adding atomic compare and swap
VarHandles were introduced in openjdk9, so the code needs to be conditionalized somehow. It is currently being developed on openjdk17. <#92>
1 parent 2bcb41f commit 04bd305

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

src/org/armedbear/lisp/Atomic.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.armedbear.lisp;
2+
3+
import static org.armedbear.lisp.Lisp.*;
4+
5+
import java.lang.invoke.MethodHandles;
6+
import java.lang.invoke.VarHandle;
7+
8+
public class Atomic
9+
{
10+
static MethodHandles.Lookup Lookup
11+
= MethodHandles.lookup();
12+
13+
static boolean compareAndSwap(LispObject place, LispObject expectedValue, LispObject newValue) {
14+
VarHandle vh = null;
15+
if (place instanceof Fixnum) {
16+
try {
17+
vh = Lookup.findVarHandle(Fixnum.class, "value", int.class);
18+
} catch (ReflectiveOperationException e) {
19+
java_error(e);
20+
return false; // unreached
21+
}
22+
}
23+
if (vh == null) {
24+
simple_error("Unable to find VarHandle for place ~a", place);
25+
return false; // unreached
26+
}
27+
return vh.compareAndSet(expectedValue, newValue);
28+
}
29+
30+
public static final Primitive _CAS = new pf_cas();
31+
@DocString(name="%cas",
32+
args="place expected-value new-value",
33+
returns="generalized boolean")
34+
private static final class pf_cas extends Primitive { // Maybe a special operator? Or do that Lisp-side?
35+
pf_cas() {
36+
super(Symbol._CAS);
37+
}
38+
@Override
39+
public LispObject execute(LispObject place, LispObject expectedValue, LispObject newValue) {
40+
boolean result = compareAndSwap (place, expectedValue, newValue);
41+
return (result == false) ? NIL : T; // TODO this has to exist somewhere as a static method
42+
}
43+
}
44+
}

src/org/armedbear/lisp/Autoload.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,5 +692,7 @@ public LispObject execute(LispObject arg)
692692
autoload(PACKAGE_EXT, "autoload-setf-expander", "AutoloadGeneralizedReference", true);
693693
autoload(PACKAGE_EXT, "autoload-setf-function", "AutoloadGeneralizedReference", true);
694694
autoload(PACKAGE_EXT, "autoload-ref-p", "AutoloadGeneralizedReference", true);
695+
696+
autoload(Symbol._CAS, "Atomic");
695697
}
696698
}

src/org/armedbear/lisp/Symbol.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2973,6 +2973,8 @@ public String toString() {
29732973
PACKAGE_EXT.addExternalSymbol("WEAK-REFERENCE");
29742974
public static final Symbol ADD_PACKAGE_LOCAL_NICKNAME =
29752975
PACKAGE_EXT.addExternalSymbol("ADD-PACKAGE-LOCAL-NICKNAME");
2976+
public static final Symbol _CAS =
2977+
PACKAGE_EXT.addExternalSymbol("%CAS");
29762978

29772979
// MOP.
29782980
public static final Symbol CLASS_LAYOUT =

0 commit comments

Comments
 (0)