ref: b0b7605bb866cccae5ea15cb9b8b18524ecc84d6
dir: /lib/thread/spawn+freebsd.myr/
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, env, envsz stk = getstk(sz) if stk == sys.Mapbad -> `std.Err "couldn't get stack" ;; tid = -1 /* find top of stack */ tos = (stk : std.intptr) + (sz : std.intptr) /* store the stack size */ tos -= sizeof(sys.size) sz -= sizeof(sys.size) szp = (tos : sys.size#) szp# = Stacksz /* store the function we call */ envsz = std.fnenvsz(fn) tos -= (envsz : std.intptr) env = tos tos -= sizeof((->void)) sz -= sizeof((->void)) fp = (tos : (->void)#) fp# = std.fnbdup(fn, (env : byte#)[:envsz]) ret = sys.thr_new(&[ .startfn = (startthread : void#), .arg = (tos : void#), .stkbase = (stk : byte#), .stksz = sz, .tid = &ctid, .ptid = &tid, .flags = 2, .rtp = (0 : sys.rtprio#) ], sizeof(sys.thrparam)) if ret < 0 -> `std.Err "couldn't spawn thread" ;; -> `std.Ok (tid : tid) } const getstk = {sz var p, m p = sys.mmap((0 : byte#), sz, sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0) if p == sys.Mapbad -> p ;; m = (p : std.intptr) -> (m : byte#) } const startthread = {fn : (-> void)# fn#() exit() }