summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2016-05-03 21:57:02 -0700
committerOri Bernstein <ori@eigenstate.org>2016-05-03 22:09:52 -0700
commit38698ba0dea7f8b8908fdd41922f4da6202a631e (patch)
treed27af0fbd7f4a83073afd00b552ce746c490812d /lib
parenta986d1d8ae4c6f75384b62347c733a226edcafba (diff)
downloadmc-38698ba0dea7f8b8908fdd41922f4da6202a631e.tar.gz
Add thread hooks
I think this makes libstd thread safe.
Diffstat (limited to 'lib')
-rw-r--r--lib/std/alloc.myr9
-rw-r--r--lib/std/bld.sub1
-rw-r--r--lib/std/env+plan9.myr20
-rw-r--r--lib/std/resolve+posixy.myr12
-rw-r--r--lib/std/threadhooks.myr43
5 files changed, 77 insertions, 8 deletions
diff --git a/lib/std/alloc.myr b/lib/std/alloc.myr
index 3209ccf..00d36b6 100644
--- 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 @@ const bytealloc = {sz
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 @@ const bytefree = {p, sz
memfill(p, 0xa8, sz)
if (sz < Bktmax)
bkt = &buckets[bktnum(sz)]
+ lock(memlck)
bktfree(bkt, p)
+ lock(memlck)
else
freemem(p, sz)
;;
diff --git a/lib/std/bld.sub b/lib/std/bld.sub
index 932fb40..638860d 100644
--- a/lib/std/bld.sub
+++ b/lib/std/bld.sub
@@ -64,6 +64,7 @@ lib std {inc=.} =
strstrip.myr
striter.myr
swap.myr
+ threadhooks.myr
try.myr
types.myr
units.myr
diff --git a/lib/std/env+plan9.myr b/lib/std/env+plan9.myr
index 2c54eea..92fed18 100644
--- 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 "sldup"
use "sleq"
use "slpush"
use "slurp"
-use "cstrconv"
+use "threadhooks"
pkg std =
const getenv : (name : byte[:] -> option(byte[:]))
@@ -22,31 +23,40 @@ var envkey : byte[:][:]
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
diff --git a/lib/std/resolve+posixy.myr b/lib/std/resolve+posixy.myr
index 344827d..2a0904b 100644
--- a/lib/std/resolve+posixy.myr
+++ b/lib/std/resolve+posixy.myr
@@ -17,6 +17,7 @@ use "slurp"
use "strfind"
use "strsplit"
use "strstrip"
+use "threadhooks"
use "types"
use "utf"
@@ -88,7 +89,11 @@ const resolverec = {host, t
}
const hostfind = {host
- -> htget(hostmap, host)
+ var h
+ lock(netlck)
+ h = htget(hostmap, host)
+ unlock(netlck)
+ -> h
}
const loadhosts = {
@@ -112,7 +117,9 @@ const loadhosts = {
| `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 @@ const addhosts = {addr, as, str
if hthas(hostmap, name)
continue
;;
+ unlock(netlck)
hinf = [
.fam=fam,
.stype = 0,
@@ -159,6 +167,7 @@ const loadresolv = {
var h
var lines
+ lock(netlck)
match slurp(Resolvfile)
| `Ok d: h = d
| `Fail m: -> void
@@ -182,6 +191,7 @@ const loadresolv = {
;;
slfree(lines)
slfree(h)
+ unlock(netlck)
}
const addns = {rest
diff --git a/lib/std/threadhooks.myr b/lib/std/threadhooks.myr
new file mode 100644
index 0000000..71f4d4c
--- /dev/null
+++ b/lib/std/threadhooks.myr
@@ -0,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
+}
+