(* ----------- Simple thread implementation --------------------*) (* ----------- Author: Andrew Appel ----------------------------*) structure Q = Queue (* Use standard Queue package *) open SMLofNJ.Cont (* Use module providing continuations *) (* The "ready queue" is the queue of threads ready to run *) val rdyQ : unit cont Q.queue = Q.mkQueue() fun exit () = throw (Q.dequeue rdyQ) () fun fork f = callcc (fn parent => (Q.enqueue (rdyQ, parent) ; (f ()) handle _ => () ; exit ())) fun yield () = callcc (fn k => (Q.enqueue (rdyQ, k) ; exit ())) (* ----------- Test program -----------------------------------*) fun rand i = (i * 109) mod 7 > 3 fun spaces 0 = () | spaces i = (print " "; spaces(i-1)) fun skipby(n,k) = let fun loop i = if i>100 then () else (spaces(10*n); print (Int.toString i ^ "\n"); if rand i then yield() else (); loop(i+k)) in loop n end fun wait 0 = () | wait n = (yield(); wait(n-1)) fun go() = (fork (fn () => skipby(0,2)); fork (fn () => skipby(1,2)); wait 200)