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
+}
+