Commit Diff


commit - dda0695dc0e5ff185e096bda7337db59e22165fb
commit + 74f990ad84deb1591ddb91be4fc8152ec0c46222
blob - /dev/null
blob + 4485671771f6839723d315dc6e25e086c309d20f (mode 644)
--- /dev/null
+++ src/libbin/bin.c
@@ -0,0 +1,111 @@
+#include <u.h>
+#include <libc.h>
+#include <bin.h>
+
+enum
+{
+	StructAlign = sizeof(union {vlong vl; double d; ulong p; void *v;
+				struct{vlong v;}vs; struct{double d;}ds; struct{ulong p;}ss; struct{void *v;}xs;})
+};
+
+enum
+{
+	BinSize	= 8*1024
+};
+
+struct Bin
+{
+	Bin	*next;
+	ulong	total;			/* total bytes allocated in can->next */
+	ulong	pos;
+	ulong	end;
+	ulong	v;			/* last value allocated */
+	uchar	body[BinSize];
+};
+
+/*
+ * allocator which allows an entire set to be freed at one time
+ */
+static Bin*
+mkbin(Bin *bin, ulong size)
+{
+	Bin *b;
+
+	size = ((size << 1) + (BinSize - 1)) & ~(BinSize - 1);
+	b = malloc(sizeof(Bin) + size - BinSize);
+	if(b == nil)
+		return nil;
+	b->next = bin;
+	b->total = 0;
+	if(bin != nil)
+		b->total = bin->total + bin->pos - (ulong)bin->body;
+	b->pos = (ulong)b->body;
+	b->end = b->pos + size;
+	return b;
+}
+
+void*
+binalloc(Bin **bin, ulong size, int zero)
+{
+	Bin *b;
+	ulong p;
+
+	if(size == 0)
+		size = 1;
+	b = *bin;
+	if(b == nil){
+		b = mkbin(nil, size);
+		if(b == nil)
+			return nil;
+		*bin = b;
+	}
+	p = b->pos;
+	p = (p + (StructAlign - 1)) & ~(StructAlign - 1);
+	if(p + size > b->end){
+		b = mkbin(b, size);
+		if(b == nil)
+			return nil;
+		*bin = b;
+		p = b->pos;
+	}
+	b->pos = p + size;
+	b->v = p;
+	if(zero)
+		memset((void*)p, 0, size);
+	return (void*)p;
+}
+
+void*
+bingrow(Bin **bin, void *op, ulong osize, ulong size, int zero)
+{
+	Bin *b;
+	void *np;
+	ulong p;
+
+	p = (ulong)op;
+	b = *bin;
+	if(b != nil && p == b->v && p + size <= b->end){
+		b->pos = p + size;
+		if(zero)
+			memset((char*)p + osize, 0, size - osize);
+		return op;
+	}
+	np = binalloc(bin, size, zero);
+	if(np == nil)
+		return nil;
+	memmove(np, op, osize);
+	return np;
+}
+
+void
+binfree(Bin **bin)
+{
+	Bin *last;
+
+	while(*bin != nil){
+		last = *bin;
+		*bin = (*bin)->next;
+		last->pos = (ulong)last->body;
+		free(last);
+	}
+}
blob - /dev/null
blob + c4501d0d3b2d07f8eb6da44b9d54fef60e678cf5 (mode 644)
--- /dev/null
+++ src/libbin/mkfile
@@ -0,0 +1,11 @@
+PLAN9=../..
+<$PLAN9/src/mkhdr
+
+LIB=libbin.a
+
+OFILES=\
+	bin.$O\
+
+HFILES=$PLAN9/include/bin.h
+
+<$PLAN9/src/mksyslib