Real Thread/yield + Thread/interrupted (jolt-l2gc)
Thread/yield was a no-op and Thread/interrupted always returned false. Now: - yield calls libc sched_yield (resolved once via the process symbols), so a spin loop relinquishes the CPU. Falls back to a zero-length park if the symbol can't be resolved. - each OS thread carries an interrupt flag (a box, thread-local). currentThread returns a handle wrapping the calling thread's flag, so .interrupt from another thread sets the target's flag. .isInterrupted reads without clearing; the static Thread/interrupted reads and clears — JVM semantics. Consolidates the Thread surface: currentThread + the instance methods live in io.ss (where the handle and its classloader are built), the flag box + yield + the interrupted static in host-static.ss. Unit cases cover yield, the read/clear split, and a cross-thread interrupt over a future.
This commit is contained in:
parent
87aec859b8
commit
980ec73933
4 changed files with 59 additions and 14 deletions
|
|
@ -117,6 +117,14 @@
|
|||
{:suite "reify" :expr "(do (defprotocol Q (qa [_]) (qb [_])) (extend-protocol Q java.lang.Object (qa [_] :da) (qb [_] :db)) (def r (reify Q (qa [_] :ra))) [(qa r) (qb r)])" :expected "[:ra :db]"}
|
||||
{:suite "interrupt" :expr "(jolt.host/run-interruptible (jolt.host/make-interrupt) (fn [] (+ 1 2)))" :expected "3"}
|
||||
{:suite "interrupt" :expr "(let [t (jolt.host/make-interrupt)] (jolt.host/interrupt! t) (try (jolt.host/run-interruptible t (fn [] (loop [i 0] (recur (inc i))))) :not-interrupted (catch :default e (:jolt/interrupted (ex-data e)))))" :expected "true"}
|
||||
{:suite "interrupt" :expr "(do (Thread/yield) :ok)" :expected ":ok"}
|
||||
{:suite "interrupt" :expr "(nil? (Thread/yield))" :expected "true"}
|
||||
{:suite "interrupt" :expr "(.isInterrupted (Thread/currentThread))" :expected "false"}
|
||||
{:suite "interrupt" :expr "(let [t (Thread/currentThread)] (.interrupt t) (.isInterrupted t))" :expected "true"}
|
||||
{:suite "interrupt" :expr "(let [t (Thread/currentThread)] (.interrupt t) [(.isInterrupted t) (.isInterrupted t)])" :expected "[true true]"}
|
||||
{:suite "interrupt" :expr "(let [t (Thread/currentThread)] (.interrupt t) [(Thread/interrupted) (Thread/interrupted)])" :expected "[true false]"}
|
||||
{:suite "interrupt" :expr "(do (.interrupt (Thread/currentThread)) (Thread/interrupted) (.isInterrupted (Thread/currentThread)))" :expected "false"}
|
||||
{:suite "interrupt" :expr "(let [t (atom nil) started (promise) go (promise) f (future (reset! t (Thread/currentThread)) (deliver started true) (deref go) (.isInterrupted (deref t)))] (deref started) (.interrupt (deref t)) (deliver go true) (deref f))" :expected "true"}
|
||||
{:suite "ns-tl" :expr "(do (in-ns (quote foo.bar)) (str *ns*))" :expected "foo.bar"}
|
||||
{:suite "ns-tl" :expr "(do (create-ns (quote my.ns)) (binding [*ns* (find-ns (quote my.ns))] (str *ns*)))" :expected "my.ns"}
|
||||
{:suite "ns-tl" :expr "(do (in-ns (quote app.core)) (def sekret 42) (in-ns (quote user)) (binding [*ns* (find-ns (quote app.core))] (load-string \"sekret\")))" :expected "42"}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue