summaryrefslogtreecommitdiff
path: root/lib/thread/spawn+freebsd.myr
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-12-14 22:28:31 -0800
committerOri Bernstein <ori@eigenstate.org>2015-12-14 22:29:20 -0800
commit85fac5706cb0c63869be6512e1d61731428e3b19 (patch)
tree9a18e4ee0f49dc267cea491ed108ce1fd5dc0e26 /lib/thread/spawn+freebsd.myr
parent317eb918900dfe2a9e37fcc5acde58400b143f5a (diff)
downloadmc-85fac5706cb0c63869be6512e1d61731428e3b19.tar.gz
Spawn and exit on FreeBSD
Diffstat (limited to 'lib/thread/spawn+freebsd.myr')
-rw-r--r--lib/thread/spawn+freebsd.myr74
1 files changed, 74 insertions, 0 deletions
diff --git a/lib/thread/spawn+freebsd.myr b/lib/thread/spawn+freebsd.myr
new file mode 100644
index 0000000..63d97fe
--- /dev/null
+++ b/lib/thread/spawn+freebsd.myr
@@ -0,0 +1,74 @@
+use sys
+use std
+
+pkg thread =
+ type tid = uint64
+
+ const spawn : (fn : (-> void) -> std.result(tid, byte[:]))
+;;
+
+
+const Stacksz = 8*std.MiB
+extern const exit : (-> void)
+
+const spawn = {fn
+ -> spawnstk(fn, Stacksz)
+}
+
+const spawnstk = {fn, sz
+ var stk : byte#, tid, ctid, ret
+ var szp, fp, tos
+
+ stk = getstk(sz)
+ if stk == sys.Mapbad
+ -> `std.Fail "couldn't get stack"
+ ;;
+ tid = -1
+ /* find top of stack */
+ tos = (stk castto(std.intptr)) + (sz castto(std.intptr))
+
+ /* store the stack size */
+ tos -= sizeof(sys.size)
+ sz -= sizeof(sys.size)
+ szp = tos castto(sys.size#)
+ szp# = Stacksz
+
+ /* store the function we call */
+ tos -= sizeof((->void))
+ sz -= sizeof((->void))
+ fp = tos castto((->void)#)
+ fp# = fn
+
+ ret = sys.thr_new(&[
+ .startfn = startthread castto(void#),
+ .arg = tos castto(void#),
+ .stkbase = stk castto(byte#),
+ .stksz = sz,
+ .tid = &ctid,
+ .ptid = &tid,
+ .flags = 2,
+ .rtp = 0 castto(sys.rtprio#)
+ ], sizeof(sys.thrparam))
+
+ if ret < 0
+ -> `std.Fail "couldn't spawn thread"
+ ;;
+ -> `std.Ok tid castto(tid)
+}
+
+const getstk = {sz
+ var p, m
+
+ p = sys.mmap(0 castto(byte#), sz, sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)
+ if p == sys.Mapbad
+ -> p
+ ;;
+ m = p castto(std.intptr)
+ -> m castto(byte#)
+}
+
+const startthread = {fn : (-> void)#
+ fn#()
+ exit()
+}
+