ref: 7a6c8bdda8b4f35db12cfde703c9b4a1eaf41b14
parent: 0a1ad9624156720395cfdbbb204a179e22a6fb79
parent: bec29fb78c83ad0fd51a22bf1fda6306a8f3934b
author: Ori Bernstein <[email protected]>
date: Wed Jul 25 16:09:07 EDT 2012
Merge branch 'master' of git+ssh://mimir.eigenstate.org/git/ori/libmyr Conflicts: test.myr
--- a/alloc.myr
+++ b/alloc.myr
@@ -13,11 +13,16 @@
/* null pointers */
const Zbyte = 0 castto(byte*)
const Zslab = 0 castto(slab*)
-const Zbin = 0 castto(bin*)
+const Zchunk = 0 castto(chunk*)
+
const Pagesz = 4096 /* on the systems this supports, anyways... */
-const Bucketmax = 1024 /* Pagesz / 4; a tolerable balance. */
+const Cachemax = 16 /* maximum number of slabs in the cache */
+const Bucketmax = 1024 /* Pagesz / 8; a balance. */
const Align = 16 /* minimum allocation alignment */
+var buckets : bucket[32] /* excessive */
+var initdone : int
+
type bucket = struct
sz : size /* aligned size */
nper : size /* max number of elements per slab */
@@ -28,17 +33,14 @@
type slab = struct
next : slab* /* the next slab on the chain */
- freehd : bin* /* the nodes we're allocating */
+ freehd : chunk* /* the nodes we're allocating */
nfree : size /* the number of free nodes */
;;
-type bin = struct /* NB: must be smaller than sizeof(slab) */
- next : bin* /* the next bin in the free list */
+type chunk = struct /* NB: must be smaller than sizeof(slab) */
+ next : chunk* /* the next chunk in the free list */
;;
-var buckets : bucket[32] /* excessive */
-var initdone : int
-
generic alloc = {-> @a*
-> bytealloc(sizeof(@a)) castto(@a*)
}
@@ -52,14 +54,14 @@
var bkt
if !initdone
- for i = 0; i < buckets.len && (Align << i) < Bucketmax; i++
- allocinit(&buckets[i], Align << i)
+ for i = 0; i < buckets.len && (Align << i) <= Bucketmax; i++
+ bktinit(&buckets[i], Align << i)
;;
initdone = 1
;;
- if (sz < Bucketmax)
- bkt = &buckets[bucketnum(sz)]
+ if (sz <= Bucketmax)
+ bkt = &buckets[bktnum(sz)]
-> bktalloc(bkt)
else
-> mmap(Zbyte, sz, Mprotrw, Mpriv | Manon, -1, 0)
@@ -70,7 +72,7 @@
var bkt
if (sz < Bucketmax)
- bkt = &buckets[bucketnum(sz)]
+ bkt = &buckets[bktnum(sz)]
bktfree(bkt, m)
else
munmap(m, sz)
@@ -77,7 +79,7 @@
;;
}
-const allocinit = {b : bucket*, sz
+const bktinit = {b : bucket*, sz
b.sz = align(sz, Align)
b.nper = (Pagesz - sizeof(slab))/b.sz
b.slabs = Zslab
@@ -91,8 +93,13 @@
var s
var b
var bnext
- var off /* offset of bin head */
+ var off /* offset of chunk head */
+ if bkt.ncache > 0
+ s = bkt.cache
+ bkt.cache = s.next
+ bkt.ncache--
+ ;;
p = mmap(Zbyte, Pagesz, Mprotrw, Mpriv | Manon, -1, 0)
if p == Mapbad
die("Unable to mmap")
@@ -102,18 +109,18 @@
s.nfree = bkt.nper
/* skip past the slab header */
off = align(sizeof(slab), Align)
- bnext = nextbin(s castto(bin*), off)
+ bnext = nextchunk(s castto(chunk*), off)
s.freehd = bnext
for i = 0; i < bkt.nper; i++
b = bnext
- bnext = nextbin(b, bkt.sz)
+ bnext = nextchunk(b, bkt.sz)
b.next = bnext
;;
- b.next = Zbin
+ b.next = Zchunk
-> s
}
-const bktalloc = {bkt : bucket*
+const bktalloc = {bkt
var s
var b
@@ -127,7 +134,7 @@
bkt.slabs = s
;;
- /* grab the first bin on the slab */
+ /* grab the first chunk on the slab */
b = s.freehd
s.freehd = b.next
s.nfree--
@@ -139,15 +146,22 @@
-> b castto(byte*)
}
-const bktfree = {bkt : bucket*, m : byte*
+const bktfree = {bkt, m
var s
var b
s = mtrunc(m, Pagesz) castto(slab*)
- b = m castto(bin*)
+ b = m castto(chunk*)
if s.nfree == 0
s.next = bkt.slabs
bkt.slabs = s
+ elif s.nfree == bkt.nper
+ if bkt.ncache < Cachemax
+ s.next = bkt.cache
+ bkt.cache = s
+ else
+ munmap(s castto(byte*), Pagesz)
+ ;;
;;
s.nfree++
b.next = s.freehd
@@ -154,16 +168,12 @@
s.freehd = b
}
-const delslab = {s : slab*
-
-}
-
-const bucketnum = {sz
+const bktnum = {sz
var i
var bktsz
bktsz = Align
- for i = 0; bktsz < Bucketmax; i++
+ for i = 0; bktsz <= Bucketmax; i++
if bktsz >= sz
-> i
;;
@@ -172,9 +182,9 @@
die("Size does not match any buckets")
}
-/* bins are variable sizes, so we can't just take a slice */
-const nextbin = {b, sz
- -> ((b castto(intptr)) + sz) castto(bin*)
+/* chunks are variable sizes, so we can't just take a slice */
+const nextchunk = {b, sz
+ -> ((b castto(intptr)) + sz) castto(chunk*)
}
const align = {v, align
--- a/test.myr
+++ b/test.myr
@@ -1,12 +1,17 @@
use std
const main = {
- var x
+ var x : byte*[1024]
+ var sz
var i
- for i = 0; i < 128; i++
- x = std.bytealloc(32)
+ for sz = 1; sz < 65536; sz *= 2
+ for i = 0; i < 1024; i++
+ x[i] = std.bytealloc(sz)
+ ;;
+ for i = 0; i < 1024; i++
+ std.bytefree(x[i], sz)
+ ;;
;;
- std.bytefree(x, 32)
std.write(1, "Hello world\n")
}