Simplify futures.
use std
-use "mutex"
-use "condvar"
-use "atomic"
+use "sem"
pkg thread =
type future(@a) = struct
- mtx : mutex
- cv : cond
- set : bool
+ sem : sem
val : @a
;;
generic mkfut : (-> future(@a)#)
generic futput : (fut : future(@a)#, val : @a -> void)
generic futget : (fut : future(@a)# -> @a)
- generic futpeek : (fut : future(@a)# -> @a)
;;
generic mkfut = {
- var fut
-
- fut = std.alloc()
- fut.mtx = mkmtx()
- fut.cv = mkcond(&fut.mtx)
- fut.set = false
- -> fut
+ -> std.mk([.sem = mksem(0)])
}
generic futput = {fut, val
fut.val = val
- xset(&fut.set, true)
- condsignal(&fut.cv)
+ sempost(&fut.sem)
}
generic futget = {fut
var val
- val = futpeek(fut)
+ semwait(&fut.sem)
+ val = fut.val
std.free(fut)
-> val
}
-generic futpeek = {fut
- if !xget(&fut.set)
- mtxlock(&fut.mtx)
- if !xget(&fut.set)
- condwait(&fut.cv)
- ;;
- mtxunlock(&fut.mtx)
- ;;
- -> fut.val
-}
-
