123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- #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);
- }
- }
|