ref: 8f1267793eb4f2bfee751dab4273496c3954950b
parent: 19ee1c535810ae802d50436a734037fa0dc18bf0
author: Ori Bernstein <[email protected]>
date: Sun Jul 22 00:42:50 EDT 2012
Get bucket numbers for more general alloc goodness.
--- a/alloc.myr
+++ b/alloc.myr
@@ -7,14 +7,16 @@
generic free : (v:@a* -> void)
const bytealloc : (sz:size -> byte*)
- const bytefree : (ptr:byte* -> void)
+ const bytefree : (m:byte*, sz:size -> void)
;;
/* null pointers */
-const Zbyte = 0 castto(byte*)
-const Zslab = 0 castto(slab*)
-const Zbin = 0 castto(bin*)
-const Pagesz = 4096 /* on the systems this supports, anyways... */
+const Zbyte = 0 castto(byte*)
+const Zslab = 0 castto(slab*)
+const Zbin = 0 castto(bin*)
+const Pagesz = 4096 /* on the systems this supports, anyways... */
+const Bucketmax = 1024 /* Pagesz / 4; a tolerable balance. */
+const Align = 16 /* minimum allocation alignment */
type bucket = struct
sz : size /* aligned size */
@@ -34,8 +36,41 @@
next : bin* /* the next bin in the free list */
;;
+var buckets : bucket[32] /* excessive number of buckets. */
+var initdone : int
+
+const bytealloc = {sz
+ var i
+ var bkt
+
+ if !initdone
+ for i = 0; i < buckets.len && (Align << i) < Bucketmax; i++
+ allocinit(&buckets[i], Align << i)
+ ;;
+ initdone = 1
+ ;;
+
+ if (sz < Bucketmax)
+ bkt = &buckets[bucketnum(sz)]
+ -> bktalloc(bkt)
+ else
+ die("Size too big for now")
+ ;;
+}
+
+const bytefree = {m, sz
+ var bkt
+
+ if (sz < Bucketmax)
+ bkt = &buckets[bucketnum(sz)]
+ bktfree(bkt, m)
+ else
+ die("Size too big for now")
+ ;;
+}
+
const allocinit = {b : bucket*, sz
- b.sz = align(sz, 16)
+ b.sz = align(sz, Align)
b.nper = (Pagesz - sizeof(slab))/b.sz
b.slabs = Zslab
b.cache = Zslab
@@ -58,7 +93,7 @@
s = p castto(slab*)
s.nfree = bkt.nper
/* skip past the slab header */
- off = align(sizeof(slab), 16)
+ off = align(sizeof(slab), Align)
b = nextbin(s castto(bin*), off)
for i = 0; i < bkt.nper; i++
b = nextbin(b, bkt.sz)
@@ -112,6 +147,20 @@
const delslab = {s : slab*
+}
+
+const bucketnum = {sz
+ var i
+ var bktsz
+
+ bktsz = Align
+ for i = 0; bktsz < Bucketmax; i++
+ if bktsz >= sz
+ -> i
+ ;;
+ bktsz *= 2
+ ;;
+ die("Size does not match any buckets")
}
/* bins are variable sizes, so we can't just take a slice */