Thread/CountDownLatch + SoftReference/ConcurrentHashMap so core.cache fully passes

Closes the last clojure.core.cache gaps (now 1314/0/0, including the 1000-thread
cache-stampede):

- java.lang.Thread over Chez fork-thread (shared heap): (Thread. thunk) + start/
  join/run/isAlive, on a "user-thread" tag distinct from Thread/currentThread's
  interrupt shim. java.util.concurrent.CountDownLatch (count/mutex/condition).
- java.util.concurrent.ConcurrentHashMap = the mutable HashMap shim; get / count /
  contains? read it (clojure.core), which SoftCache uses on its backing map.
- java.lang.ref.SoftReference / ReferenceQueue: no JVM GC reference semantics, so
  the referent is held strongly (a SoftCache is unbounded rather than GC-evicting),
  but enqueue / poll work so clear-soft-cache! drains the queue.

JVM-certified corpus rows. make test + shakesmoke green.
This commit is contained in:
Yogthos 2026-06-25 11:15:12 -04:00
parent 5d0989a860
commit 9312ad0937
3 changed files with 98 additions and 0 deletions

View file

@ -11,6 +11,10 @@
{:suite "interop / iterator-seq" :label "iterator-seq over .iterator" :expected "[:a :b]" :actual "(vec (iterator-seq (.iterator [:a :b])))"}
{:suite "deftype / IPersistentStack" :label "peek/pop dispatch" :expected "[1 [2 3]]" :actual "(do (deftype Stk [v] clojure.lang.IPersistentStack (peek [_] (first v)) (pop [_] (->Stk (rest v)))) [(peek (->Stk [1 2 3])) (vec (.v (pop (->Stk [1 2 3]))))])"}
{:suite "deftype / equiv" :label "(= deftype other) uses equiv method" :expected "true" :actual "(do (deftype EqT [m] clojure.lang.IPersistentCollection (equiv [_ o] (= o m)) clojure.lang.Seqable (seq [_] (seq m))) (= (->EqT {:a 1}) {:a 1}))"}
{:suite "interop / Thread" :label "start + join runs the thunk" :expected "7" :actual "(let [a (atom 0) t (Thread. (fn [] (reset! a 7)))] (.start t) (.join t) (deref a))"}
{:suite "interop / CountDownLatch" :label "countDown to zero, await returns" :expected "0" :actual "(let [l (java.util.concurrent.CountDownLatch. 1)] (.countDown l) (.await l) (.getCount l))"}
{:suite "interop / SoftReference" :label "get returns the referent" :expected ":v" :actual "(.get (java.lang.ref.SoftReference. :v))"}
{:suite "interop / ConcurrentHashMap" :label "put + get/count/contains?" :expected "[1 1 true]" :actual "(let [m (java.util.concurrent.ConcurrentHashMap.)] (.put m :a 1) [(get m :a) (count m) (contains? m :a)])"}
{:suite "interop / Class.forName" :label "unknown class throws ClassNotFoundException" :expected ":nf" :actual "(try (Class/forName \"no.such.Klass\") (catch ClassNotFoundException _ :nf))"}
{:suite "interop / Class.forName" :label "known class resolves" :expected "\"java.lang.String\"" :actual "(.getName (Class/forName \"java.lang.String\"))"}
{:suite "clojure.string / replace" :label "char match and replacement" :expected "\"a-b-c\"" :actual "(clojure.string/replace \"a/b/c\" \\/ \\-)"}