#include "all.h" #include "mem.h" #include "io.h" ulong niob; ulong nhiob; Hiob *hiob; void prbanks(void) { Mbank *b; int m; for(m = 0; m < mconf.nbank; m++){ b = mconf.bank+m; print("bank[%d]: base %#p, limit %#p\n", m, b->base, b->limit); } } /* * Called to allocate permanent data structures * Alignment is in number of bytes. It pertains both to the start and * end of the allocated memory. */ void* ialloc(ulong n, int align) { Mbank *b; ulong p; int m; ilock(&mconf); for(b = mconf.bank; b < mconf.bank+mconf.nbank; b++){ p = b->base; if(align <= 0) align = 4; if(m = n % align) n += align - m; if(m = p % align) p += align - m; if(p+n > b->limit) continue; b->base = p+n; iunlock(&mconf); memset((void*)(p+KZERO), 0, n); return (void*)(p+KZERO); } iunlock(&mconf); prbanks(); panic("ialloc(%ld, %ld): out of memory: %#p\n", n, align, getcallerpc(&n)); return 0; } static void cmd_memory(int, char *[]) { prbanks(); } /* * allocate rest of mem * for io buffers. */ #define HWIDTH 8 /* buffers per hash */ void iobufinit(void) { ulong m, i; Iobuf *p, *q; Hiob *hp; Mbank *b; wlock(&mainlock); /* init */ wunlock(&mainlock); prbanks(); m = 0; for(b = mconf.bank; b < mconf.bank+mconf.nbank; b++) m += b->limit - b->base; m -= conf.sparemem; niob = m / (sizeof(Iobuf) + RBUFSIZE + sizeof(Hiob)/HWIDTH); nhiob = niob / HWIDTH; while(!prime(nhiob)) nhiob++; print(" %ld buffers; %ld hashes\n", niob, nhiob); hiob = ialloc(nhiob * sizeof(Hiob), 0); hp = hiob; for(i=0; inamebuf, sizeof hp->namebuf, "hiob%uld\n", i); hp->name = hp->namebuf; qlock(hp); qunlock(hp); hp++; } p = ialloc(niob * sizeof(Iobuf), 0); hp = hiob; for(i=0; iname = "buf"; snprint(p->namebuf, sizeof p->namebuf, "buf%uld", i); p->name = p->namebuf; qlock(p); qunlock(p); if(hp == hiob) hp = hiob + nhiob; hp--; q = hp->link; if(q) { p->fore = q; p->back = q->back; q->back = p; p->back->fore = p; } else { hp->link = p; p->fore = p; p->back = p; } p->dev = devnone; p->addr = -1; p->xiobuf = ialloc(RBUFSIZE, RBUFSIZE); p->iobuf = (char*)-1; p++; } /* * Make sure that no more of bank[0] can be used: * 'check' will do an ialloc(0, 1) to find the base of * sparemem. */ if(mconf.bank[0].limit < 1024*1024) mconf.bank[0].base = mconf.bank[0].limit+1; i = 0; for(b = mconf.bank; b < mconf.bank+mconf.nbank; b++) i += b->limit - b->base; print(" mem left = %,uld, out of %,uld\n", i, conf.mem); /* paranoia: add this command as late as is easy */ cmd_install("memory", "-- print ranges of memory banks", cmd_memory); } void* iobufmap(Iobuf *p) { return p->iobuf = p->xiobuf; } void iobufunmap(Iobuf *p) { p->iobuf = (char*)-1; }