ref: b31626248ea64c23d2020846e2cac1c751348b61
dir: /lib/thread/queue.myr/
use std use "mutex" use "condvar" pkg thread = type queue(@a) = struct hd : qnode(@a)# tl : qnode(@a)# mtx : mutex cv : cond ;; type qnode(@a) = struct v : @a next : qnode(@a)# ;; generic qinit : (q : queue(@a)# -> void) generic qget : (q : queue(@a)# -> @a) generic qput : (q : queue(@a)#, v : @a -> void) ;; generic Znode = (0 : qnode(@a)#) generic qinit = {q q.hd = Znode q.tl = Znode q.mtx = mkmtx() q.cv = mkcond(&q.mtx) } generic qput = {q, v : @a var n : qnode(@a)# n = std.mk([.next=Znode, .v=v]) mtxlock(&q.mtx) if q.hd == Znode q.hd = n q.tl = n else q.tl.next = n q.tl = n ;; condsignal(&q.cv) mtxunlock(&q.mtx) } generic qget = {q var n, v mtxlock(&q.mtx) :again if q.hd == Znode condwait(&q.cv) goto again else n = q.hd q.hd = q.hd.next ;; mtxunlock(&q.mtx) v = n.v std.free(n) -> v }