tadd libbin - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 74f990ad84deb1591ddb91be4fc8152ec0c46222
 (DIR) parent dda0695dc0e5ff185e096bda7337db59e22165fb
 (HTM) Author: rsc <devnull@localhost>
       Date:   Sun, 23 Nov 2003 18:11:44 +0000
       
       add libbin
       
       Diffstat:
         A src/libbin/bin.c                    |     111 ++++++++++++++++++++++++++++++
         A src/libbin/mkfile                   |      11 +++++++++++
       
       2 files changed, 122 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/src/libbin/bin.c b/src/libbin/bin.c
       t@@ -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);
       +        }
       +}
 (DIR) diff --git a/src/libbin/mkfile b/src/libbin/mkfile
       t@@ -0,0 +1,11 @@
       +PLAN9=../..
       +<$PLAN9/src/mkhdr
       +
       +LIB=libbin.a
       +
       +OFILES=\
       +        bin.$O\
       +
       +HFILES=$PLAN9/include/bin.h
       +
       +<$PLAN9/src/mksyslib