allocb.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       allocb.c (3448B)
       ---
            1 #include        "u.h"
            2 #include        "lib.h"
            3 #include        "mem.h"
            4 #include        "dat.h"
            5 #include        "fns.h"
            6 #include        "error.h"
            7 
            8 enum
            9 {
           10         Hdrspc                = 64,                /* leave room for high-level headers */
           11         Bdead                = 0x51494F42,        /* "QIOB" */
           12 };
           13 
           14 struct
           15 {
           16         Lock lk;
           17         ulong        bytes;
           18 } ialloc;
           19 
           20 static Block*
           21 _allocb(int size)
           22 {
           23         Block *b;
           24         ulong addr;
           25 
           26         if((b = mallocz(sizeof(Block)+size+Hdrspc, 0)) == nil)
           27                 return nil;
           28 
           29         b->next = nil;
           30         b->list = nil;
           31         b->free = 0;
           32         b->flag = 0;
           33         b->ref = 0;
           34 
           35         /* align start of data portion by rounding up */
           36         addr = (ulong)b;
           37         addr = ROUND(addr + sizeof(Block), BLOCKALIGN);
           38         b->base = (uchar*)addr;
           39 
           40         /* align end of data portion by rounding down */
           41         b->lim = ((uchar*)b) + sizeof(Block)+size+Hdrspc;
           42         addr = (ulong)(b->lim);
           43         addr = addr & ~(BLOCKALIGN-1);
           44         b->lim = (uchar*)addr;
           45 
           46         /* leave sluff at beginning for added headers */
           47         b->rp = b->lim - ROUND(size, BLOCKALIGN);
           48         if(b->rp < b->base)
           49                 panic("_allocb");
           50         b->wp = b->rp;
           51 
           52         return b;
           53 }
           54 
           55 Block*
           56 allocb(int size)
           57 {
           58         Block *b;
           59 
           60         /*
           61          * Check in a process and wait until successful.
           62          * Can still error out of here, though.
           63          */
           64         if(up == nil)
           65                 panic("allocb without up: %#p", getcallerpc(&size));
           66         if((b = _allocb(size)) == nil){
           67                 xsummary();
           68                 mallocsummary();
           69                 panic("allocb: no memory for %d bytes", size);
           70         }
           71         setmalloctag(b, getcallerpc(&size));
           72 
           73         return b;
           74 }
           75 
           76 Block*
           77 iallocb(int size)
           78 {
           79         Block *b;
           80         static int m1, m2, mp;
           81 
           82         if(ialloc.bytes > conf.ialloc){
           83                 if((m1++%10000)==0){
           84                         if(mp++ > 1000){
           85                                 active.exiting = 1;
           86                                 panic("iallocb");
           87                         }
           88                         iprint("iallocb: limited %lud/%lud\n",
           89                                 ialloc.bytes, conf.ialloc);
           90                 }
           91                 return nil;
           92         }
           93 
           94         if((b = _allocb(size)) == nil){
           95                 if((m2++%10000)==0){
           96                         if(mp++ > 1000){
           97                                 active.exiting = 1;
           98                                 panic("iallocb");
           99                         }
          100                         iprint("iallocb: no memory %lud/%lud\n",
          101                                 ialloc.bytes, conf.ialloc);
          102                 }
          103                 return nil;
          104         }
          105         setmalloctag(b, getcallerpc(&size));
          106         b->flag = BINTR;
          107 
          108         ilock(&ialloc.lk);
          109         ialloc.bytes += b->lim - b->base;
          110         iunlock(&ialloc.lk);
          111 
          112         return b;
          113 }
          114 
          115 void
          116 freeb(Block *b)
          117 {
          118         void *dead = (void*)Bdead;
          119         long ref;
          120 
          121         if(b == nil)
          122                 return;
          123 
          124         if(0){
          125                 dumpstack();
          126                 panic("freeb: ref %ld; caller pc %#p", ref, getcallerpc(&b));
          127         }
          128 
          129         /*
          130          * drivers which perform non cache coherent DMA manage their own buffer
          131          * pool of uncached buffers and provide their own free routine.
          132          */
          133         if(b->free) {
          134                 b->free(b);
          135                 return;
          136         }
          137         if(b->flag & BINTR) {
          138                 ilock(&ialloc.lk);
          139                 ialloc.bytes -= b->lim - b->base;
          140                 iunlock(&ialloc.lk);
          141         }
          142 
          143         /* poison the block in case someone is still holding onto it */
          144         b->next = dead;
          145         b->rp = dead;
          146         b->wp = dead;
          147         b->lim = dead;
          148         b->base = dead;
          149 
          150         free(b);
          151 }
          152 
          153 void
          154 checkb(Block *b, char *msg)
          155 {
          156         void *dead = (void*)Bdead;
          157 
          158         if(b == dead)
          159                 panic("checkb b %s %#p", msg, b);
          160         if(b->base == dead || b->lim == dead || b->next == dead
          161           || b->rp == dead || b->wp == dead){
          162                 print("checkb: base %#p lim %#p next %#p\n",
          163                         b->base, b->lim, b->next);
          164                 print("checkb: rp %#p wp %#p\n", b->rp, b->wp);
          165                 panic("checkb dead: %s", msg);
          166         }
          167 
          168         if(b->base > b->lim)
          169                 panic("checkb 0 %s %#p %#p", msg, b->base, b->lim);
          170         if(b->rp < b->base)
          171                 panic("checkb 1 %s %#p %#p", msg, b->base, b->rp);
          172         if(b->wp < b->base)
          173                 panic("checkb 2 %s %#p %#p", msg, b->base, b->wp);
          174         if(b->rp > b->lim)
          175                 panic("checkb 3 %s %#p %#p", msg, b->rp, b->lim);
          176         if(b->wp > b->lim)
          177                 panic("checkb 4 %s %#p %#p", msg, b->wp, b->lim);
          178 }
          179 
          180 void
          181 iallocsummary(void)
          182 {
          183         print("ialloc %lud/%lud\n", ialloc.bytes, conf.ialloc);
          184 }