;; -*- Mode: Irken -*-

(include "lib/basis.scm")

(define run-queue (queue/make))

(define (enqueue k)
  (queue/add run-queue k))

(define (dispatch)
  (match (queue/pop run-queue) with
    (maybe:yes k) -> (k #u)
    (maybe:no) -> #u))

(define (fork f)
  (call/cc
   (lambda (k)
     (enqueue k)
     (f)
     (dispatch)
     )))

(define (yield)
  (call/cc
   (lambda (k)
     (enqueue k)
     (dispatch)
     )))

(define (thread n)
  (for-range
      i 10
      (print-string (format "thread# " (int n) ":" (int i) "\n"))
      (yield)
      ))

(print-string "first fork\n")
(fork (lambda () (thread 0)))
(print-string "second fork\n")
(fork (lambda () (thread 1)))
(thread 2)
(print-string (format "queue length = " (int run-queue.length) "\n"))