71 lines · 1.3 KB · Text
RawDownload
use sysuse std use "common"use "tls"use "types" pkg thread =	const spawn : (fn : (-> void) -> std.result(tid, byte[:]));; const Stacksz = 8*std.MiBextern const exit : (-> void) /* Holy shit flag mania. */const Thrflag = sys.Clonevm | sys.Clonefs | sys.Clonefiles | \	sys.Clonesighand | sys.Clonethread | sys.Clonesettls | \	sys.Clonechildsettid const spawn = {fn	-> spawnstk(fn, Stacksz)} const spawnstk = {fn, sz	var stk, tos, hdr, ret 	stk = sys.mmap((0 : byte#), sz, sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)	if stk == sys.Mapbad		-> `std.Err "couldn't get stack"	;;	(tos, hdr) = initstk(stk, fn, sz) 	ret = sys.fnclone(Thrflag,		tos,		Zptr,		(hdr : byte#),		(&hdr.tid : sys.pid#),		Zptr,		(startthread : void#))	if ret < 0		sys.munmap(stk, sz)		-> `std.Err "couldn't spawn thread"	;;	-> `std.Ok (ret : tid)} const initstk = {stk, fn, sz	var len, tos, hdr, fp, env, envsz 	len = tlslen()	tos = (stk : std.intptr) + (sz : std.intptr)	tos -= (sizeof(tlshdr) + ((len : std.intptr) * sizeof(void#)) + 0xf) & ~0xf	hdr = (tos : tlshdr#)	hdr.len = len	hdr.base = stk	hdr.stksz = sz 	envsz = std.fnenvsz(fn)	tos -= (envsz : std.intptr)	env = tos	tos -= sizeof((->void))	fp = (tos : (->void)#)	fp# = std.fnbdup(fn, (env : byte#)[:envsz])	-> ((tos : byte#), hdr)} const startthread = {fn : (-> void)	fn()	exit()}