shithub: mc

Download patch

ref: 38698ba0dea7f8b8908fdd41922f4da6202a631e
parent: a986d1d8ae4c6f75384b62347c733a226edcafba
author: Ori Bernstein <ori@eigenstate.org>
date: Tue May 3 17:57:02 EDT 2016

Add thread hooks

	I think this makes libstd thread safe.

--- a/lib/std/alloc.myr
+++ b/lib/std/alloc.myr
@@ -1,9 +1,10 @@
 use "die"
 use "extremum"
+use "memops"
+use "syswrap"
+use "threadhooks"
 use "types"
 use "units"
-use "syswrap"
-use "memops"
 
 /*
 The allocator implementation here is based on Bonwick's slab allocator.
@@ -231,7 +232,9 @@
 
 	if (sz <= Bktmax)
 		bkt = &buckets[bktnum(sz)]
+		lock(memlck)
 		p = bktalloc(bkt)
+		unlock(memlck)
 	else
 		p = getmem(sz)
 		if p == Failmem
@@ -248,7 +251,9 @@
 	memfill(p, 0xa8, sz)
 	if (sz < Bktmax)
 		bkt = &buckets[bktnum(sz)]
+		lock(memlck)
 		bktfree(bkt, p)
+		lock(memlck)
 	else
 		freemem(p, sz)
 	;;
--- a/lib/std/bld.sub
+++ b/lib/std/bld.sub
@@ -64,6 +64,7 @@
 	strstrip.myr
 	striter.myr
 	swap.myr
+	threadhooks.myr
 	try.myr
 	types.myr
 	units.myr
--- a/lib/std/env+plan9.myr
+++ b/lib/std/env+plan9.myr
@@ -1,6 +1,7 @@
 use sys
 
 use "alloc"
+use "cstrconv"
 use "die"
 use "extremum"
 use "fmt"
@@ -11,7 +12,7 @@
 use "sleq"
 use "slpush"
 use "slurp"
-use "cstrconv"
+use "threadhooks"
 
 pkg std =
 	const getenv :	(name : byte[:] -> option(byte[:]))
@@ -22,31 +23,40 @@
 var envval	: byte[:][:]
 
 const envfind = {key
+	lock(envlck)
 	for var i = 0; i < envkey.len; i++
 		if std.sleq(envkey[i], key)
+			unlock(envlck)
 			-> `Some envval[i]
 		;;
 	;;
+	unlock(envlck)
 	-> `None
 }
 
 const getenv = {name
 	var buf : byte[128]
-	var s
+	var s, ret
 
 	match envfind(name)
-	| `Some val:	-> `Some val
+	| `Some val:
+		ret = `Some val
 	| `None:
 		s = bfmt(buf[:], "/env/{}", name)
 		match std.slurp(s)
-		| `Fail m: -> `None
+		| `Fail m: 
+			ret = `None
 		| `Ok data:
 			data = cstrconv(data)
+			lock(envlck)
 			slpush(&envkey, sldup(data))
 			slpush(&envval, data)
-			-> `Some data
+			unlock(envlck)
+			ret = `Some data
 		;;
+		std.slfree(s)
 	;;
+	-> ret
 }
 
 const getenvv = {name, default
--- a/lib/std/resolve+posixy.myr
+++ b/lib/std/resolve+posixy.myr
@@ -17,6 +17,7 @@
 use "strfind"
 use "strsplit"
 use "strstrip"
+use "threadhooks"
 use "types"
 use "utf"
 
@@ -88,7 +89,11 @@
 }
 
 const hostfind = {host
-	-> htget(hostmap, host)
+	var h
+	lock(netlck)
+	h = htget(hostmap, host)
+	unlock(netlck)
+	-> h
 }
 
 const loadhosts = {
@@ -112,7 +117,9 @@
 		| `Some (ip, rest):
 			match ipparse(ip)
 			| `Some addr:
+				lock(netlck)
 				addhosts(addr, ip, rest)
+				unlock(netlck)
 			| `None:
 				/*
 				invalid addresses are ignored: we don't want to break stuff
@@ -142,6 +149,7 @@
 			if hthas(hostmap, name)
 				continue
 			;;
+			unlock(netlck)
 			hinf = [
 				.fam=fam,
 				.stype = 0,
@@ -159,6 +167,7 @@
 	var h
 	var lines
 
+	lock(netlck)
 	match slurp(Resolvfile)
 	| `Ok d:	h = d
 	| `Fail m:	-> void
@@ -182,6 +191,7 @@
 	;;
 	slfree(lines)
 	slfree(h)
+	unlock(netlck)
 }
 
 const addns = {rest
--- /dev/null
+++ b/lib/std/threadhooks.myr
@@ -1,0 +1,43 @@
+use "die"
+
+pkg std =
+	pkglocal var lock	: (l : void# -> void)
+	pkglocal var unlock	: (l : void# -> void)
+	pkglocal var memlck	: void#
+	pkglocal var netlck	: void#
+	pkglocal var envlck	: void#
+
+	const __lockinit	: ( \
+		mem : void#, \
+		net : void#, \
+		env : void#, \
+		lck : (l : void# -> void), \
+		unlck : (l : void# -> void) \
+		-> void)
+;;
+
+/* thread lock wrapper functions */
+var lock
+var unlock
+
+/* locks for various parts of libstd */
+var memlck
+var netlck
+var envlck
+/*
+work around compiler bug: we don't generate
+syms for the funcs with an initializer
+*/
+const __init__ = {
+	lock = {l; }
+	unlock = {l; }
+}
+
+const __lockinit = {mem, net, env, lck, unlck
+	memlck = mem
+	netlck = net
+	envlck = env
+	lock = lck
+	unlock = unlck
+}
+