Skip to content

Commit

Permalink
Explorations in adding atomic compare and swap
Browse files Browse the repository at this point in the history
VarHandles were introduced in openjdk9, so the code needs to be
conditionalized somehow.  It is currently being developed on
openjdk17.

<#92>
  • Loading branch information
easye committed Jun 29, 2023
1 parent 55b2806 commit 2a88f22
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
44 changes: 44 additions & 0 deletions src/org/armedbear/lisp/Atomic.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.armedbear.lisp;

import static org.armedbear.lisp.Lisp.*;

import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;

public class Atomic
{
static MethodHandles.Lookup Lookup
= MethodHandles.lookup();

static boolean compareAndSwap(LispObject place, LispObject expectedValue, LispObject newValue) {
VarHandle vh = null;
if (place instanceof Fixnum) {
try {
vh = Lookup.findVarHandle(Fixnum.class, "value", int.class);
} catch (ReflectiveOperationException e) {
java_error(e);
return false; // unreached
}
}
if (vh == null) {
simple_error("Unable to find VarHandle for place ~a", place);
return false; // unreached
}
return vh.compareAndSet(expectedValue, newValue);
}

public static final Primitive _CAS = new pf_cas();
@DocString(name="%cas",
args="place expected-value new-value",
returns="generalized boolean")
private static final class pf_cas extends Primitive { // Maybe a special operator? Or do that Lisp-side?
pf_cas() {
super(Symbol._CAS);
}
@Override
public LispObject execute(LispObject place, LispObject expectedValue, LispObject newValue) {
boolean result = compareAndSwap (place, expectedValue, newValue);
return (result == false) ? NIL : T; // TODO this has to exist somewhere as a static method
}
}
}
2 changes: 2 additions & 0 deletions src/org/armedbear/lisp/Autoload.java
Original file line number Diff line number Diff line change
Expand Up @@ -692,5 +692,7 @@ public LispObject execute(LispObject arg)
autoload(PACKAGE_EXT, "autoload-setf-expander", "AutoloadGeneralizedReference", true);
autoload(PACKAGE_EXT, "autoload-setf-function", "AutoloadGeneralizedReference", true);
autoload(PACKAGE_EXT, "autoload-ref-p", "AutoloadGeneralizedReference", true);

autoload(Symbol._CAS, "Atomic");
}
}
2 changes: 2 additions & 0 deletions src/org/armedbear/lisp/Symbol.java
Original file line number Diff line number Diff line change
Expand Up @@ -2973,6 +2973,8 @@ public String toString() {
PACKAGE_EXT.addExternalSymbol("WEAK-REFERENCE");
public static final Symbol ADD_PACKAGE_LOCAL_NICKNAME =
PACKAGE_EXT.addExternalSymbol("ADD-PACKAGE-LOCAL-NICKNAME");
public static final Symbol _CAS =
PACKAGE_EXT.addExternalSymbol("%CAS");

// MOP.
public static final Symbol CLASS_LAYOUT =
Expand Down

0 comments on commit 2a88f22

Please sign in to comment.