Skip to content

Instantly share code, notes, and snippets.

@ryepup
Created November 21, 2010 06:04
Show Gist options
  • Save ryepup/708502 to your computer and use it in GitHub Desktop.
Save ryepup/708502 to your computer and use it in GitHub Desktop.
coroutines with bordeaux-threads (broken)
(defmacro make-coroutine ((&key (coroutine-done-value :done)) &body body)
(alexandria:with-gensyms ((yield-cv "can we yield?")
(run-cv "can we run?")
(run-lck "lock for the runner thread")
(val "yielding value")
(thrfn "thread body"))
`(let* ((,yield-cv (bordeaux-threads:make-condition-variable
:name "yield"))
(,run-cv (bordeaux-threads:make-condition-variable
:name "run"))
(,run-lck (bordeaux-threads:make-lock "run lock"))
,val
(,thrfn (lambda ()
(flet ((yield (&optional n)
(setf ,val n)
;; tell interested parties a value is ready
(bordeaux-threads:condition-notify ,yield-cv)
;;wait for a chance to run
(bordeaux-threads:condition-wait ,run-cv ,run-lck)
,val))
(bordeaux-threads:acquire-lock ,run-lck)
,@body
(yield ,coroutine-done-value)))))
;;function to pull values from the coroutine
(let ((alive-p T)
thr)
(lambda ()
(unless thr
(setf thr (bordeaux-threads:make-thread
,thrfn :name "coroutine")))
(when (and alive-p (bordeaux-threads:thread-alive-p thr))
;; tell the coroutine to run
(bordeaux-threads:with-lock-held (,run-lck)
(bordeaux-threads:condition-notify ,run-cv)
(bordeaux-threads:condition-wait ,yield-cv ,run-lck))
(when (eql ,coroutine-done-value ,val)
(bordeaux-threads:destroy-thread thr)
(setf alive-p nil)))
,val)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment