use sysuse std pkg thread = type tid = sys.pid const spawn : (fn : (-> void) -> std.result(tid, byte[:]));; extern const exit : (-> void) /* Holy shit flag mania. */const Thrflag = sys.Clonevm | sys.Clonefs | sys.Clonefiles | \ sys.Clonesighand | sys.Clonethread |sys.Clonesysvsem | \ sys.Clonesettls | sys.Cloneparentsettid | sys.Clonechildcleartid const Stacksz = 8*std.MiB 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" ;; tos = stk castto(std.intptr) tos -= sizeof(int64) szp = tos castto(sys.size#) szp# = Stacksz tos -= sizeof((->void)) fp = tos castto((->void)#) fp# = fn ret = sys.fnclone(Thrflag, \ tos castto(byte#),\ &tid, 0 castto(byte#), \ &ctid, 0 castto(byte#), \ startthread castto(void#)) castto(tid) if ret < 0 std.put("errno={}\n", -ret) -> `std.Fail "couldn't spawn thread" ;; -> `std.Ok ret} 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 ;; /* stack starts at the top of memory and grows down. */ m = p castto(std.intptr) m += sz castto(std.intptr) -> m castto(byte#)} const startthread = {fn : (-> void) fn() exit()}
use sys
use std
pkg thread =
type tid = sys.pid
const spawn : (fn : (-> void) -> std.result(tid, byte[:]))
;;
extern const exit : (-> void)
/* Holy shit flag mania. */
const Thrflag = sys.Clonevm | sys.Clonefs | sys.Clonefiles | \
sys.Clonesighand | sys.Clonethread |sys.Clonesysvsem | \
sys.Clonesettls | sys.Cloneparentsettid | sys.Clonechildcleartid
const Stacksz = 8*std.MiB
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"
;;
tos = stk castto(std.intptr)
tos -= sizeof(int64)
szp = tos castto(sys.size#)
szp# = Stacksz
tos -= sizeof((->void))
fp = tos castto((->void)#)
fp# = fn
ret = sys.fnclone(Thrflag, \
tos castto(byte#),\
&tid, 0 castto(byte#), \
&ctid, 0 castto(byte#), \
startthread castto(void#)) castto(tid)
if ret < 0
std.put("errno={}\n", -ret)
-> `std.Fail "couldn't spawn thread"
;;
-> `std.Ok ret
}
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
;;
/* stack starts at the top of memory and grows down. */
m = p castto(std.intptr)
m += sz castto(std.intptr)
-> m castto(byte#)
}
const startthread = {fn : (-> void)
fn()
exit()
}