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/alloc.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 #include        <pool.h>
    8 
    9 static void poolprint(Pool*, char*, ...);
   10 static void ppanic(Pool*, char*, ...);
   11 static void plock(Pool*);
   12 static void punlock(Pool*);
   13 
   14 typedef struct Private  Private;
   15 struct Private {
   16         Lock            lk;
   17         char            msg[256];       /* a rock for messages to be printed at unlock */
   18 };
   19 
   20 static Private pmainpriv;
   21 static Pool pmainmem = {
   22         .name=  "Main",
   23         .maxsize=       4*1024*1024,
   24         .minarena=      128*1024,
   25         .quantum=       32,
   26         .alloc= xalloc,
   27         .merge= xmerge,
   28         .flags= POOL_TOLERANCE,
   29 
   30         .lock=  plock,
   31         .unlock=        punlock,
   32         .print= poolprint,
   33         .panic= ppanic,
   34 
   35         .private=       &pmainpriv,
   36 };
   37 
   38 static Private pimagpriv;
   39 static Pool pimagmem = {
   40         .name=  "Image",
   41         .maxsize=       16*1024*1024,
   42         .minarena=      2*1024*1024,
   43         .quantum=       32,
   44         .alloc= xalloc,
   45         .merge= xmerge,
   46         .flags= 0,
   47 
   48         .lock=  plock,
   49         .unlock=        punlock,
   50         .print= poolprint,
   51         .panic= ppanic,
   52 
   53         .private=       &pimagpriv,
   54 };
   55 
   56 Pool*   mainmem = &pmainmem;
   57 Pool*   imagmem = &pimagmem;
   58 
   59 /*
   60  * because we can't print while we're holding the locks, 
   61  * we have the save the message and print it once we let go.
   62  */
   63 static void
   64 poolprint(Pool *p, char *fmt, ...)
   65 {
   66         va_list v;
   67         Private *pv;
   68 
   69         pv = p->private;
   70         va_start(v, fmt);
   71         vseprint(pv->msg+strlen(pv->msg), pv->msg+sizeof pv->msg, fmt, v);
   72         va_end(v);
   73 }
   74 
   75 static void
   76 ppanic(Pool *p, char *fmt, ...)
   77 {
   78         va_list v;
   79         Private *pv;
   80         char msg[sizeof pv->msg];
   81 
   82         pv = p->private;
   83         va_start(v, fmt);
   84         vseprint(pv->msg+strlen(pv->msg), pv->msg+sizeof pv->msg, fmt, v);
   85         va_end(v);
   86         memmove(msg, pv->msg, sizeof msg);
   87         iunlock(&pv->lk);
   88         panic("%s", msg);
   89 }
   90 
   91 static void
   92 plock(Pool *p)
   93 {
   94         Private *pv;
   95 
   96         pv = p->private;
   97         ilock(&pv->lk);
   98         pv->lk.pc = getcallerpc(&p);
   99         pv->msg[0] = 0;
  100 }
  101 
  102 static void
  103 punlock(Pool *p)
  104 {
  105         Private *pv;
  106         char msg[sizeof pv->msg];
  107 
  108         pv = p->private;
  109         if(pv->msg[0] == 0){
  110                 iunlock(&pv->lk);
  111                 return;
  112         }
  113 
  114         memmove(msg, pv->msg, sizeof msg);
  115         iunlock(&pv->lk);
  116         iprint("%.*s", sizeof pv->msg, msg);
  117 }
  118 
  119 void
  120 poolsummary(Pool *p)
  121 {
  122         print("%s max %lud cur %lud free %lud alloc %lud\n", p->name,
  123                 p->maxsize, p->cursize, p->curfree, p->curalloc);
  124 }
  125 
  126 void
  127 mallocsummary(void)
  128 {
  129         poolsummary(mainmem);
  130         poolsummary(imagmem);
  131 }
  132 
  133 /* everything from here down should be the same in libc, libdebugmalloc, and the kernel */
  134 /* - except the code for malloc(), which alternately doesn't clear or does. */
  135 /* - except the code for smalloc(), which lives only in the kernel. */
  136 
  137 /*
  138  * Npadlong is the number of 32-bit longs to leave at the beginning of 
  139  * each allocated buffer for our own bookkeeping.  We return to the callers
  140  * a pointer that points immediately after our bookkeeping area.  Incoming pointers
  141  * must be decremented by that much, and outgoing pointers incremented.
  142  * The malloc tag is stored at MallocOffset from the beginning of the block,
  143  * and the realloc tag at ReallocOffset.  The offsets are from the true beginning
  144  * of the block, not the beginning the caller sees.
  145  *
  146  * The extra if(Npadlong != 0) in various places is a hint for the compiler to
  147  * compile out function calls that would otherwise be no-ops.
  148  */
  149 
  150 /*      non tracing
  151  *
  152 enum {
  153         Npadlong        = 0,
  154         MallocOffset = 0,
  155         ReallocOffset = 0,
  156 };
  157  *
  158  */
  159 
  160 /* tracing */
  161 enum {
  162         Npadlong        = 2,
  163         MallocOffset = 0,
  164         ReallocOffset = 1
  165 };
  166 
  167 
  168 void*
  169 smalloc(ulong size)
  170 {
  171         void *v;
  172 
  173         for(;;) {
  174                 v = poolalloc(mainmem, size+Npadlong*sizeof(ulong));
  175                 if(v != nil)
  176                         break;
  177                 tsleep(&up->sleep, return0, 0, 100);
  178         }
  179         if(Npadlong){
  180                 v = (ulong*)v+Npadlong;
  181                 setmalloctag(v, getcallerpc(&size));
  182         }
  183         memset(v, 0, size);
  184         return v;
  185 }
  186 
  187 void*
  188 malloc(ulong size)
  189 {
  190         void *v;
  191 
  192         v = poolalloc(mainmem, size+Npadlong*sizeof(ulong));
  193         if(v == nil)
  194                 return nil;
  195         if(Npadlong){
  196                 v = (ulong*)v+Npadlong;
  197                 setmalloctag(v, getcallerpc(&size));
  198                 setrealloctag(v, 0);
  199         }
  200         memset(v, 0, size);
  201         return v;
  202 }
  203 
  204 void*
  205 mallocz(ulong size, int clr)
  206 {
  207         void *v;
  208 
  209         v = poolalloc(mainmem, size+Npadlong*sizeof(ulong));
  210         if(Npadlong && v != nil){
  211                 v = (ulong*)v+Npadlong;
  212                 setmalloctag(v, getcallerpc(&size));
  213                 setrealloctag(v, 0);
  214         }
  215         if(clr && v != nil)
  216                 memset(v, 0, size);
  217         return v;
  218 }
  219 
  220 void*
  221 mallocalign(ulong size, ulong align, long offset, ulong span)
  222 {
  223         void *v;
  224 
  225         v = poolallocalign(mainmem, size+Npadlong*sizeof(ulong), align, offset-Npadlong*sizeof(ulong), span);
  226         if(Npadlong && v != nil){
  227                 v = (ulong*)v+Npadlong;
  228                 setmalloctag(v, getcallerpc(&size));
  229                 setrealloctag(v, 0);
  230         }
  231         if(v)
  232                 memset(v, 0, size);
  233         return v;
  234 }
  235 
  236 void
  237 free(void *v)
  238 {
  239         if(v != nil)
  240                 poolfree(mainmem, (ulong*)v-Npadlong);
  241 }
  242 
  243 void*
  244 realloc(void *v, ulong size)
  245 {
  246         void *nv;
  247 
  248         if(v != nil)
  249                 v = (ulong*)v-Npadlong;
  250         if(Npadlong !=0 && size != 0)
  251                 size += Npadlong*sizeof(ulong);
  252 
  253         if(nv = poolrealloc(mainmem, v, size)){
  254                 nv = (ulong*)nv+Npadlong;
  255                 setrealloctag(nv, getcallerpc(&v));
  256                 if(v == nil)
  257                         setmalloctag(nv, getcallerpc(&v));
  258         }               
  259         return nv;
  260 }
  261 
  262 ulong
  263 msize(void *v)
  264 {
  265         return poolmsize(mainmem, (ulong*)v-Npadlong)-Npadlong*sizeof(ulong);
  266 }
  267 
  268 void*
  269 calloc(ulong n, ulong szelem)
  270 {
  271         void *v;
  272         if(v = mallocz(n*szelem, 1))
  273                 setmalloctag(v, getcallerpc(&n));
  274         return v;
  275 }
  276 
  277 void
  278 setmalloctag(void *v, ulong pc)
  279 {
  280         ulong *u;
  281         USED(v, pc);
  282         if(Npadlong <= MallocOffset || v == nil)
  283                 return;
  284         u = v;
  285         u[-Npadlong+MallocOffset] = pc;
  286 }
  287 
  288 void
  289 setrealloctag(void *v, ulong pc)
  290 {
  291         ulong *u;
  292         USED(v, pc);
  293         if(Npadlong <= ReallocOffset || v == nil)
  294                 return;
  295         u = v;
  296         u[-Npadlong+ReallocOffset] = pc;
  297 }
  298 
  299 ulong
  300 getmalloctag(void *v)
  301 {
  302         USED(v);
  303         if(Npadlong <= MallocOffset)
  304                 return ~0;
  305         return ((ulong*)v)[-Npadlong+MallocOffset];
  306 }
  307 
  308 ulong
  309 getrealloctag(void *v)
  310 {
  311         USED(v);
  312         if(Npadlong <= ReallocOffset)
  313                 return ((ulong*)v)[-Npadlong+ReallocOffset];
  314         return ~0;
  315 }

Cache object: 86dde55b70d1f0f6c73abce839b91fa3


[ 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.