Code: Select all
#!/usr/bin/env newlisp
(context 'spawn)
(set '_procs '())
(set '_counter (semaphore))
(define-macro (spawn:spawn)
(println (semaphore _counter))
(if (> 4 (semaphore _counter)) (spawn:sync))
(semaphore _counter (+ 1 (semaphore _counter)))
(let ((target-symbol (args 0))
(expr (args 1))
(shared (share)))
(push
(list shared target-symbol
(letex ((body expr))
(fork
(begin
(set 'spawn:_procs '())
(share shared body)
(exit)))))
_procs -1)))
(define (spawn:sync)
(let ((proc (pop _procs)))
(when proc
(letex ((shared (proc 0))
(target (proc 1))
(pid (proc 2)))
(wait-pid pid)
(semaphore _counter (- (semaphore _counter) 1))
(set target (share shared))
(share nil shared)))))
(context MAIN)
(define (sync)
(while (spawn:sync)))
(constant (global 'sync))
(define (fib n , x y)
(if (< n 2) 2
(begin
(spawn 'x (fib (- n 1)))
(spawn 'y (fib (- n 2)))
(sync)
(+ x y))))
(define (fib2 n)
(if (< n 2) 2
(+ (fib2 (- n 1)) (fib2 (- n 2)))))
(println (fib 10))
(println (fib2 10))