Chez concurrency pt.1: real OS-thread futures + blocking promises (shared heap)
future/future-call run the body on a native thread (fork-thread) over the SAME heap — JVM semantics, not Janet's isolated-heap snapshot. deref blocks on a mutex+condition latch; timed (deref f ms val) uses an absolute deadline. promise is a real blocking promise (deref parks until deliver), replacing the Janet non-blocking atom shim. future?/future-done?/future-cancelled?/future-cancel /realized? are native (the overlay versions read Janet map keys); re-asserted in post-prelude over the overlay. pmap/pcalls/pvalues (overlay, over future) light up for free. Thread-safety this forces: - atoms get a per-atom mutex; swap!/swap-vals! are a JVM-style CAS loop (f runs outside the lock, so a watch/validator can deref the same atom); reset!/ compare-and-set! are atomic. - the dynamic binding stack becomes a Chez thread-parameter, so each future/thread has its own; Chez inherits it at fork, giving binding conveyance (the shim also installs an explicit snapshot). - Thread/sleep really sleeps now (a worker sleeping doesn't block the parent). Re-minted the seed: future-call now resolves at compile time, so pmap compiles to a var-deref instead of the host-static-call fallback that crashed. image.ss unchanged. Corpus: the 2 snapshot cases now match the JVM (shared) not Janet (isolated) — allowlisted on both Chez gates; the two racy future-cancel cases allowlisted; "promise undelivered" (blocks on JVM/Chez, profile :bucket :timeout) skipped like :throws. Zero-Janet corpus 2544 -> 2569, 0 new divergences, floor raised. Full Janet gate + JVM cert green. jolt-byjr
This commit is contained in:
parent
a23095b502
commit
ec30c9e405
10 changed files with 330 additions and 42 deletions
|
|
@ -128,9 +128,16 @@
|
|||
(cons "PI" (->num (* 4 (atan 1)))) (cons "E" (->num (exp 1)))
|
||||
(cons "random" (lambda args (->num (random 1.0))))))
|
||||
|
||||
;; Thread: no real threading here (futures/timing are jolt-byjr). sleep is a no-op.
|
||||
;; Thread: real OS threads back futures/promises (jolt-byjr), so sleep genuinely
|
||||
;; parks the calling thread for `ms` milliseconds (a worker sleeping doesn't block
|
||||
;; the parent). yield hands off the scheduler.
|
||||
(register-class-statics! "Thread"
|
||||
(list (cons "sleep" (lambda (ms . _) jolt-nil))
|
||||
(list (cons "sleep" (lambda (ms . _)
|
||||
(let* ((ms* (exact (floor ms)))
|
||||
(secs (quotient ms* 1000))
|
||||
(nanos (* (remainder ms* 1000) 1000000)))
|
||||
(sleep (make-time 'time-duration nanos secs)))
|
||||
jolt-nil))
|
||||
(cons "yield" (lambda () jolt-nil))
|
||||
(cons "interrupted" (lambda () #f))
|
||||
(cons "currentThread" (lambda () (make-jhost "thread" '())))))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue