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/xalloc.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 
    7 enum
    8 {
    9         Chunk           = 64*1024,
   10         Nhole           = 128,
   11         Magichole       = 0x484F4C45,                   /* HOLE */
   12 };
   13 
   14 typedef struct Hole Hole;
   15 typedef struct Xalloc Xalloc;
   16 typedef struct Xhdr Xhdr;
   17 
   18 struct Hole
   19 {
   20         ulong   addr;
   21         ulong   size;
   22         ulong   top;
   23         Hole*   link;
   24 };
   25 
   26 struct Xhdr
   27 {
   28         ulong   size;
   29         ulong   magix;
   30         char    data[];
   31 };
   32 
   33 struct Xalloc
   34 {
   35         Lock;
   36         Hole    hole[Nhole];
   37         Hole*   flist;
   38         Hole*   table;
   39 };
   40 
   41 static Xalloc   xlists;
   42 
   43 void
   44 xinit(void)
   45 {
   46         int i, n, upages, kpages;
   47         ulong maxpages;
   48         Confmem *m;
   49         Pallocmem *pm;
   50         Hole *h, *eh;
   51 
   52         eh = &xlists.hole[Nhole-1];
   53         for(h = xlists.hole; h < eh; h++)
   54                 h->link = h+1;
   55 
   56         xlists.flist = xlists.hole;
   57 
   58         upages = conf.upages;
   59         kpages = conf.npage - upages;
   60         pm = palloc.mem;
   61         for(i=0; i<nelem(conf.mem); i++){
   62                 m = &conf.mem[i];
   63                 n = m->npage;
   64                 if(n > kpages)
   65                         n = kpages;
   66                 /* don't try to use non-KADDR-able memory for kernel */
   67                 maxpages = cankaddr(m->base)/BY2PG;
   68                 if(n > maxpages)
   69                         n = maxpages;
   70                 /* first give to kernel */
   71                 if(n > 0){
   72                         m->kbase = (ulong)KADDR(m->base);
   73                         m->klimit = (ulong)KADDR(m->base+n*BY2PG);
   74                         xhole(m->base, n*BY2PG);
   75                         kpages -= n;
   76                 }
   77                 /* if anything left over, give to user */
   78                 if(n < m->npage){
   79                         if(pm >= palloc.mem+nelem(palloc.mem)){
   80                                 print("xinit: losing %lud pages\n", m->npage-n);
   81                                 continue;
   82                         }
   83                         pm->base = m->base+n*BY2PG;
   84                         pm->npage = m->npage - n;
   85                         pm++;
   86                 }
   87         }
   88         xsummary();
   89 }
   90 
   91 void*
   92 xspanalloc(ulong size, int align, ulong span)
   93 {
   94         ulong a, v, t;
   95         a = (ulong)xalloc(size+align+span);
   96         if(a == 0)
   97                 panic("xspanalloc: %lud %d %lux\n", size, align, span);
   98 
   99         if(span > 2) {
  100                 v = (a + span) & ~(span-1);
  101                 t = v - a;
  102                 if(t > 0)
  103                         xhole(PADDR(a), t);
  104                 t = a + span - v;
  105                 if(t > 0)
  106                         xhole(PADDR(v+size+align), t);
  107         }
  108         else
  109                 v = a;
  110 
  111         if(align > 1)
  112                 v = (v + align) & ~(align-1);
  113 
  114         return (void*)v;
  115 }
  116 
  117 void*
  118 xallocz(ulong size, int zero)
  119 {
  120         Xhdr *p;
  121         Hole *h, **l;
  122 
  123         size += BY2V + offsetof(Xhdr, data[0]);
  124         size &= ~(BY2V-1);
  125 
  126         ilock(&xlists);
  127         l = &xlists.table;
  128         for(h = *l; h; h = h->link) {
  129                 if(h->size >= size) {
  130                         p = (Xhdr*)KADDR(h->addr);
  131                         h->addr += size;
  132                         h->size -= size;
  133                         if(h->size == 0) {
  134                                 *l = h->link;
  135                                 h->link = xlists.flist;
  136                                 xlists.flist = h;
  137                         }
  138                         iunlock(&xlists);
  139                         if(zero)
  140                                 memset(p->data, 0, size);
  141                         p->magix = Magichole;
  142                         p->size = size;
  143                         return p->data;
  144                 }
  145                 l = &h->link;
  146         }
  147         iunlock(&xlists);
  148         return nil;
  149 }
  150 
  151 void*
  152 xalloc(ulong size)
  153 {
  154         return xallocz(size, 1);
  155 }
  156 
  157 void
  158 xfree(void *p)
  159 {
  160         Xhdr *x;
  161 
  162         x = (Xhdr*)((ulong)p - offsetof(Xhdr, data[0]));
  163         if(x->magix != Magichole) {
  164                 xsummary();
  165                 panic("xfree(%#p) %#ux != %#lux", p, Magichole, x->magix);
  166         }
  167         xhole(PADDR((uintptr)x), x->size);
  168 }
  169 
  170 int
  171 xmerge(void *vp, void *vq)
  172 {
  173         Xhdr *p, *q;
  174 
  175         p = (Xhdr*)(((ulong)vp - offsetof(Xhdr, data[0])));
  176         q = (Xhdr*)(((ulong)vq - offsetof(Xhdr, data[0])));
  177         if(p->magix != Magichole || q->magix != Magichole) {
  178                 xsummary();
  179                 panic("xmerge(%#p, %#p) bad magic %#lux, %#lux\n",
  180                         vp, vq, p->magix, q->magix);
  181         }
  182         if((uchar*)p+p->size == (uchar*)q) {
  183                 p->size += q->size;
  184                 return 1;
  185         }
  186         return 0;
  187 }
  188 
  189 void
  190 xhole(ulong addr, ulong size)
  191 {
  192         ulong top;
  193         Hole *h, *c, **l;
  194 
  195         if(size == 0)
  196                 return;
  197 
  198         top = addr + size;
  199         ilock(&xlists);
  200         l = &xlists.table;
  201         for(h = *l; h; h = h->link) {
  202                 if(h->top == addr) {
  203                         h->size += size;
  204                         h->top = h->addr+h->size;
  205                         c = h->link;
  206                         if(c && h->top == c->addr) {
  207                                 h->top += c->size;
  208                                 h->size += c->size;
  209                                 h->link = c->link;
  210                                 c->link = xlists.flist;
  211                                 xlists.flist = c;
  212                         }
  213                         iunlock(&xlists);
  214                         return;
  215                 }
  216                 if(h->addr > addr)
  217                         break;
  218                 l = &h->link;
  219         }
  220         if(h && top == h->addr) {
  221                 h->addr -= size;
  222                 h->size += size;
  223                 iunlock(&xlists);
  224                 return;
  225         }
  226 
  227         if(xlists.flist == nil) {
  228                 iunlock(&xlists);
  229                 print("xfree: no free holes, leaked %lud bytes\n", size);
  230                 return;
  231         }
  232 
  233         h = xlists.flist;
  234         xlists.flist = h->link;
  235         h->addr = addr;
  236         h->top = top;
  237         h->size = size;
  238         h->link = *l;
  239         *l = h;
  240         iunlock(&xlists);
  241 }
  242 
  243 void
  244 xsummary(void)
  245 {
  246         int i;
  247         Hole *h;
  248 
  249         i = 0;
  250         for(h = xlists.flist; h; h = h->link)
  251                 i++;
  252 
  253         print("%d holes free\n", i);
  254         i = 0;
  255         for(h = xlists.table; h; h = h->link) {
  256                 print("%.8lux %.8lux %lud\n", h->addr, h->top, h->size);
  257                 i += h->size;
  258         }
  259         print("%d bytes free\n", i);
  260 }

Cache object: 6e2abee5e4b1ca5a5093f95ff1a882ab


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