The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/port/allocb.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 0059afaf593cb8563a4d32225eec7aee


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.