task scheduler added by megane on Fri Feb 17 16:40:41 2023
(module main () (import (chicken base) scheme)
(import matchable)
(import srfi-18)
(import (chicken process))
(define guard (make-mutex))
(define next-id 1)
(define n-running-threads 1)
(define dones '())
;; (module . #pre-reqs . successors)
(define modules '((a 0 b d1)
(b 1 c)
(e 0 c)
(c 3)
(d1 1 d2)
(d2 1 d3)
(d3 1 c)))
(define (runner-loop id)
(mutex-lock! guard)
(let loop ([ms modules]
[r '()])
(match ms
[()
(set! n-running-threads (sub1 n-running-threads))
(mutex-unlock! guard)
(print id ": nothing to run")]
[((m 0 . succs) . rest)
(set! modules (append (reverse r) rest))
;; Add more parallelism
(set! n-running-threads (add1 n-running-threads))
(thread-start! (make-thread (lambda () (runner-loop next-id))))
(set! next-id (add1 next-id))
(mutex-unlock! guard)
(print id ": running " m)
(let [(pid (process-run "sleep 1"))]
(let loop ()
(receive (pid2 ok? status) (process-wait pid #t)
(when (= 0 pid2)
(thread-sleep! .1)
(loop)))))
(print id ": ran " m)
(mutex-lock! guard)
(set! dones (cons m dones))
;; Decrement successor counters
(for-each (lambda (succ)
(and-let* ([m2 (assq succ modules)])
(set-car! (cdr m2) (sub1 (cadr m2)))))
succs)
(mutex-unlock! guard)
(runner-loop id)]
[(m . rest)
(loop (cdr ms) (cons m r))])))
(runner-loop 0)
(let loop ()
(mutex-lock! guard)
(unless (= 0 n-running-threads)
(mutex-unlock! guard)
(print "primordial sleep")
(thread-sleep! 1)
(loop)))
(print "primordial thread stopping")
(print (reverse dones))
)