diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libbin |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libbin')
-rwxr-xr-x | sys/src/libbin/bin.c | 111 | ||||
-rwxr-xr-x | sys/src/libbin/mkfile | 16 |
2 files changed, 127 insertions, 0 deletions
diff --git a/sys/src/libbin/bin.c b/sys/src/libbin/bin.c new file mode 100755 index 000000000..323a2f9b7 --- /dev/null +++ b/sys/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 */ + uintptr pos; + uintptr end; + uintptr 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 - (uintptr)bin->body; + b->pos = (uintptr)b->body; + b->end = b->pos + size; + return b; +} + +void* +binalloc(Bin **bin, ulong size, int zero) +{ + Bin *b; + uintptr 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; + uintptr p; + + p = (uintptr)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 = (uintptr)last->body; + free(last); + } +} diff --git a/sys/src/libbin/mkfile b/sys/src/libbin/mkfile new file mode 100755 index 000000000..9fe11194a --- /dev/null +++ b/sys/src/libbin/mkfile @@ -0,0 +1,16 @@ +</$objtype/mkfile + +LIB=/$objtype/lib/libbin.a +OFILES=\ + bin.$O\ + +HFILES=\ + /sys/include/bin.h\ + +UPDATE=\ + mkfile\ + $HFILES\ + ${OFILES:%.$O=%.c}\ + ${LIB:/$objtype/%=/386/%}\ + +</sys/src/cmd/mksyslib |