shithub: mc

Download patch

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")
 }