shithub: mc

ref: b4a8cf6eb24355953d0510d74a19966938907de8
dir: /lib/thread/spawn+linux.myr/

View raw version
use sys
use std

pkg thread =
	type tid = sys.pid

	const spawn : (fn : (-> void) -> std.result(tid, byte[:]))
;;

/* 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, tid, ctid, ret

	stk = getstk(sz)
	if stk == sys.Mapbad
		-> `std.Fail "couldn't get stack"
	;;

	ret = sys.fnclone(Thrflag, stk, &tid, 0 castto(byte#), &ctid, 0 castto(byte#), fn) 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#)
}