M port/alloc.c => port/alloc.c +205 -43
@@ 3,18 3,25 @@
#include "mem.h"
#include "dat.h"
#include "fns.h"
-#define nil ((void*)0)
-#define datoff ((int)&((Xhdr*)0)->data)
+
+#define nil ((void*)0)
+#define datoff ((ulong)&((Xhdr*)0)->data)
+#define bdatoff ((ulong)&((Bucket*)0)->data)
enum
{
- Nhole = 128,
- Magic = 0xDeadBabe,
+ Maxpow = 16,
+ Nhole = 128,
+ Magichole = 0xDeadBabe,
+ Magic2n = 0xBadC0c0a,
};
typedef struct Hole Hole;
typedef struct Xalloc Xalloc;
typedef struct Xhdr Xhdr;
+typedef struct Bucket Bucket;
+typedef struct Arena Arena;
+
struct Hole
{
ulong addr;
@@ 38,62 45,95 @@ struct Xalloc
Hole *table;
};
-Xalloc xlists;
+struct Bucket
+{
+ int size;
+ int magic;
+ Bucket *next;
+ char data[1];
+};
+
+struct Arena
+{
+ Lock;
+ Bucket *btab[Maxpow];
+};
+
+static Arena arena;
+static Xalloc xlists;
+
+void*
+ialloc(ulong size, int align)
+{
+ ulong p;
+
+ if(align) {
+ size += BY2PG;
+ p = (ulong)xalloc(size);
+ p += BY2PG;
+ p &= ~(BY2PG-1);
+ return (void*)p;
+ }
+
+ return xalloc(size);
+}
+
+void*
+iallocspan(ulong size, int quanta, ulong span)
+{
+ return ialloc(size, quanta);
+}
void
xinit(void)
{
+ ulong ktop;
Hole *h, *eh;
+ int up, np0, np1;
eh = &xlists.hole[Nhole-1];
for(h = xlists.hole; h < eh; h++)
h->link = h+1;
- xlists.flist = h;
-}
+ xlists.flist = xlists.hole;
-void
-xhole(ulong addr, ulong size)
-{
- Hole *h, **l;
+ ktop = PGROUND((ulong)end);
+ ktop = PADDR(ktop);
+ conf.npage0 -= ktop/BY2PG;
+ conf.base0 += ktop;
- lock(&xlists);
- l = &xlists.table;
- for(h = *l; h; h = h->link) {
- if(h->top == addr) {
- h->size += size;
- h->top = h->addr+h->size;
- unlock(&xlists);
- return;
- }
- if(h->addr > addr)
- break;
- l = &h->link;
- }
+ up = conf.upages;
+ np1 = up;
+ if(np1 > conf.npage1)
+ np1 = conf.npage1;
- if(xlists.flist == nil) {
- print("xfree: no free holes, leaked %d bytes\n", size);
- unlock(&xlists);
- return;
- }
+ palloc.p1 = conf.base1;
+ conf.base1 += np1*BY2PG;
+ conf.npage1 -= np1;
+ xhole(conf.base1, conf.npage1*BY2PG);
+ up -= np1;
- h = xlists.flist;
- xlists.flist = h->link;
- h->addr = addr;
- h->top = addr+size;
- h->size = size;
- h->link = *l;
- *l = h;
- unlock(&xlists);
+ np0 = up;
+ if(np0 > conf.npage0)
+ np0 = conf.npage0;
+
+ palloc.p0 = conf.base0;
+ conf.base0 += np0*BY2PG;
+ conf.npage0 -= np0;
+ xhole(conf.base0, conf.npage0*BY2PG);
+
+ palloc.np0 = np0;
+ palloc.np1 = np1;
}
void*
xalloc(ulong size)
{
- Hole *h, **l;
Xhdr *p;
+ Hole *h, **l;
- size += sizeof(Xhdr);
+ size += BY2WD + sizeof(Xhdr);
+ size &= ~(BY2WD-1);
lock(&xlists);
l = &xlists.table;
@@ 107,7 147,9 @@ xalloc(ulong size)
h->link = xlists.flist;
xlists.flist = h;
}
- p->magix = Magic;
+ p = KADDR(p);
+ memset(p, 0, size);
+ p->magix = Magichole;
p->size = size;
unlock(&xlists);
return p->data;
@@ 124,10 166,64 @@ xfree(void *p)
Xhdr *x;
x = (Xhdr*)((ulong)p - datoff);
- if(x->magix != Magic)
+ if(x->magix != Magichole)
panic("xfree");
- xhole((ulong)x, x->size);
+ xhole(PADDR(x), x->size);
+}
+
+void
+xhole(ulong addr, ulong size)
+{
+ ulong top;
+ Hole *h, *c, **l;
+
+ if(size == 0)
+ return;
+
+ top = addr + size;
+ lock(&xlists);
+ l = &xlists.table;
+ for(h = *l; h; h = h->link) {
+ if(h->top == addr) {
+ h->size += size;
+ h->top = h->addr+h->size;
+ c = h->link;
+ if(c && h->top == c->addr) {
+ h->top += c->size;
+ h->size += c->size;
+ h->link = c->link;
+ c->link = xlists.flist;
+ xlists.flist = c;
+ }
+ unlock(&xlists);
+ return;
+ }
+ if(h->addr > addr)
+ break;
+ l = &h->link;
+ }
+ if(h && top == h->addr) {
+ h->addr -= size;
+ h->size += size;
+ unlock(&xlists);
+ return;
+ }
+
+ if(xlists.flist == nil) {
+ unlock(&xlists);
+ print("xfree: no free holes, leaked %d bytes\n", size);
+ return;
+ }
+
+ h = xlists.flist;
+ xlists.flist = h->link;
+ h->addr = addr;
+ h->top = top;
+ h->size = size;
+ h->link = *l;
+ *l = h;
+ unlock(&xlists);
}
void
@@ 143,8 239,74 @@ xsummary(void)
print("%d holes free\n", i);
i = 0;
for(h = xlists.table; h; h = h->link) {
- print("%lux %lux %d\n", h->addr, h->top, h->size);
+ print("%.8lux %.8lux %d\n", h->addr, h->top, h->size);
i += h->size;
}
print("%d bytes free\n", i);
}
+
+void*
+malloc(ulong size)
+{
+ int pow;
+ Bucket *bp;
+
+ for(pow = 1; pow < Maxpow; pow++)
+ if(size <= (1<<pow))
+ goto good;
+
+ return nil;
+good:
+ /* Allocate off this list */
+ lock(&arena);
+ bp = arena.btab[pow];
+ if(bp) {
+ arena.btab[pow] = bp->next;
+ unlock(&arena);
+
+ if(bp->magic != 0)
+ panic("malloc");
+
+ bp->magic = Magic2n;
+
+ memset(bp->data, 0, size);
+ return bp->data;
+ }
+ unlock(&arena);
+ size = sizeof(Bucket)+(1<<pow);
+ bp = xalloc(size);
+ if(bp == nil)
+ return nil;
+
+ bp->size = pow;
+ bp->magic = Magic2n;
+ return bp->data;
+}
+
+void*
+smalloc(ulong size)
+{
+ void *p;
+
+ p = malloc(size);
+ if(p == nil)
+ panic("smalloc should sleep");
+ return p;
+}
+
+void
+free(void *ptr)
+{
+ Bucket *bp, **l;
+
+ bp = (Bucket*)((ulong)ptr - bdatoff);
+ if(bp->magic != Magic2n)
+ panic("free");
+
+ bp->magic = 0;
+ lock(&arena);
+ l = &arena.btab[bp->size];
+ bp->next = *l;
+ *l = bp;
+ unlock(&arena);
+}
M port/chan.c => port/chan.c +3 -4
@@ 91,7 91,6 @@ newchan(void)
c->mnt = 0;
c->stream = 0;
c->aux = 0;
- c->mntindex = 0;
c->mchan = 0;
c->mqid = (Qid){0, 0};
return c;
@@ 178,7 177,7 @@ mount(Chan *new, Chan *old, int flag)
}
if(m == 0) {
- m = newmnthead();
+ m = smalloc(sizeof(Mhead));
m->from = old;
incref(old);
m->hash = *l;
@@ 238,7 237,7 @@ unmount(Chan *mnt, Chan *mounted)
wunlock(&pg->ns);
mountfree(m->mount);
close(m->from);
- mntheadfree(m);
+ free(m);
return;
}
@@ 252,7 251,7 @@ unmount(Chan *mnt, Chan *mounted)
*l = m->hash;
wunlock(&pg->ns);
close(m->from);
- mntheadfree(m);
+ free(m);
return;
}
wunlock(&pg->ns);
M port/dev.c => port/dev.c +0 -2
@@ 7,8 7,6 @@
#define DEVTAB
#include "devtab.h"
-#include "fcall.h"
-
extern ulong kerndate;
int
M port/devarp.c => port/devarp.c +1 -1
@@ 332,7 332,7 @@ arpoput(Queue *q, Block *bp)
/* if ip broadcast, use ether bcast address */
addr = nhgetl(eh->dst);
- if(addr == Myip[Mybcast] || addr == Myip[Mynet]
+ if(Myip[Myself] == 0 || addr == Myip[Mybcast] || addr == Myip[Mynet]
|| ((addr & Mymask) == Myip[Mynet+1] && (addr & ~Mynetmask) == ~Mynetmask)){
memset(eh->d, 0xff, sizeof(eh->d));
PUTNEXT(q, bp);
M port/devcons.c => port/devcons.c +3 -0
@@ 228,6 228,9 @@ echo(Rune r, char *buf, int n)
switch(r){
case 0x14:
break; /* pass it on */
+ case 'x':
+ xsummary();
+ break;
case 'd':
consdebug();
return;
M port/devip.c => port/devip.c +0 -1
@@ 93,7 93,6 @@ ipreset(void)
}
initfrag(conf.frag);
- tcpinit();
}
void
M port/devmnt.c => port/devmnt.c +0 -1
@@ 5,7 5,6 @@
#include "fns.h"
#include "../port/error.h"
#include "devtab.h"
-#include "fcall.h"
typedef struct Mntrpc Mntrpc;
typedef struct Mnt Mnt;
M port/devpipe.c => port/devpipe.c +0 -1
@@ 6,7 6,6 @@
#include "../port/error.h"
#include "devtab.h"
-#include "fcall.h"
typedef struct Pipe Pipe;
M port/devproc.c => port/devproc.c +0 -5
@@ 4,7 4,6 @@
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
-#include "fcall.h"
#include "ureg.h"
#include "devtab.h"
@@ 264,10 263,6 @@ procread(Chan *c, void *va, long n, ulong offset)
}
if(offset >= KZERO) {
- /* prevent users reading authentication crypt keys */
- if(offset >= pgrpalloc.cryptbase)
- if(offset < pgrpalloc.crypttop)
- error(Eperm);
/* validate physical kernel addresses */
if(offset < KZERO+conf.npage0*BY2PG){
if(offset+n > KZERO+conf.npage0*BY2PG)
M port/fcall.c => port/fcall.c +1 -1
@@ 1,6 1,6 @@
#include <u.h>
#include <libc.h>
-#include <fcall.h>
+#include "fcall.h"
#define CHAR(x) *p++ = f->x
#define SHORT(x) p[0] = f->x; p[1] = f->x>>8; p += 2
D port/malloc.c => port/malloc.c +0 -85
@@ 1,85 0,0 @@
-#include <u.h>
-#include <libc.h>
-
-enum
-{
- MAGIC = 0xDEADBABE,
- MAXPOW = 20
-};
-
-typedef struct Bucket Bucket;
-struct Bucket
-{
- int size;
- int magic;
- Bucket *next;
- char data[1];
-};
-
-typedef struct Arena Arena;
-struct Arena
-{
- Lock;
- Bucket *btab[MAXPOW];
-};
-static Arena arena;
-#define datoff ((int)&((Bucket*)0)->data)
-
-void*
-malloc(uint size)
-{
- int pow;
- Bucket *bp;
-
- size += sizeof(Bucket);
-
- for(pow = 1; pow < MAXPOW; pow++)
- if(size <= (1<<pow))
- goto good;
-
- return 0;
-
-good:
- lock(&arena);
- bp = arena.btab[pow];
- if(bp) {
- arena.btab[pow] = bp->next;
- arena.unlock();
-
- if(bp->magic != 0)
- panic("malloc");
-
- bp->magic = MAGIC;
-
- memset(bp->data, 0, size);
- return bp->data;
- }
- unlock(&arena);
-
- size = sizeof(Bucket)+(1<<pow);
- bp = xbrk(size);
- if((int)bp < 0)
- return nil;
-
- memset(bp->data, 0, size);
- return bp->data;
-}
-
-void
-free(void *ptr)
-{
- Bucket *bp, **l;
-
- /* Find the start of the structure */
- bp = (Bucket*)((uint)ptr - datoff);
-
- if(bp->magic != MAGIC)
- panic("free");
-
- bp->magic = 0;
- lock(&arena);
- l = &arena.btab[bp->size];
- bp->next = *l;
- *l = bp;
- unlock(&arena);
-}
M port/net.c => port/net.c +0 -2
@@ 5,8 5,6 @@
#include "fns.h"
#include "../port/error.h"
-#include "fcall.h"
-
enum
{
Qlisten= 1,
M port/page.c => port/page.c +57 -217
@@ 8,8 8,6 @@
#define PGHFUN(x, y) (((ulong)x^(ulong)y)%PGHSIZE)
#define pghash(s) palloc.hash[PGHFUN(s->image, p->daddr)]
-struct Palloc palloc;
-
struct Ptealloc
{
Lock;
@@ 17,240 15,55 @@ struct Ptealloc
int pages;
}ptealloclk;
-ulong hiaddr;
-static Lock pglock;
-
-/* Multiplex a hardware lock for per page manipulations */
-void
-lockpage(Page *p)
-{
- int s;
-
- for(;;) {
- if(p->lock == 0) {
- s = splhi();
- lock(&pglock);
- if(p->lock == 0) {
- p->lock = 1;
- unlock(&pglock);
- splx(s);
- return;
- }
- unlock(&pglock);
- splx(s);
- }
- sched();
- }
-}
-
-void
-unlockpage(Page *p)
-{
- p->lock = 0;
-}
-
-typedef struct Region Region;
-struct Region
-{
- ulong start;
- ulong end;
-};
-
-enum
-{
- Nregion= 10,
-};
-Region region[Nregion];
-
-
-void
-addsplit(Region *r, ulong start, ulong end)
-{
- int len;
- Region *rr, *eregion;
-
- len = end - start;
- eregion = ®ion[Nregion];
-
- /* first look for an unused one */
- for(rr = region; rr < eregion; rr++){
- if(rr == r)
- continue;
- if(rr->end - rr->start == 0){
- rr->start = start;
- rr->end = end;
- return;
- }
- }
-
- /* then look for a smaller one */
- for(rr = region; rr < eregion; rr++){
- if(rr == r)
- continue;
- if(rr->end - rr->start < len){
- rr->start = start;
- rr->end = end;
- return;
- }
- }
-}
-
-/*
- * Called to allocate permanent data structures, before calling pageinit().
- * We assume all of text+data+bss is in the first memory bank.
- *
- * alignment is in number of bytes. It pertains both to the start and
- * end of the allocated memory.
- *
- * If crevasse is specified, no allocation can span an address that is
- * a multiple of crevasse.
- */
-void*
-iallocspan(ulong n, int align, ulong crevasse)
-{
- int m;
- ulong p;
- Region *r;
- int ledge;
-
- if(palloc.active && n!=0)
- print("ialloc bad\n");
-
- if(palloc.addr0 == 0){
- r = ®ion[Nregion-2];
- r->start = (((ulong)end)&~KZERO) + conf.base0;
- r->end = conf.base0 + (conf.npage0<<PGSHIFT);
- r++;
- r->start = conf.base1;
- r->end = conf.base1 + (conf.npage1<<PGSHIFT);
-
- palloc.addr0 = region[Nregion-2].start;
- palloc.addr1 = region[Nregion-1].start;
- }
-
- /*
- * alignment also applies to length
- */
- if(align){
- m = n % align;
- if(m)
- n += align - m;
- }
-
- p = 0;
- for(r = region; r < ®ion[Nregion]; r++){
- /* align region */
- p = r->start;
- if(align){
- m = p % align;
- if(m)
- p += align - m;
- }
-
- /* check for crossing a crevasse */
- if(crevasse){
- ledge = p / crevasse;
- if(ledge != ((p+n-1) / crevasse))
- p = ((p+n-1) / crevasse) * crevasse;
- }
-
- /* see if it fits */
- if(p + n > r->end)
- continue;
-
- /* split the region */
- if(p != r->start)
- addsplit(r, r->start, p);
- r->start = p + n;
- break;
- }
- if(r == ®ion[Nregion])
- panic("out of memory");
-
- /*
- * remember high water marks
- */
- if(palloc.addr0 < r->start && r->start <= conf.base0+(conf.npage0<<PGSHIFT))
- palloc.addr0 = r->start;
- else if(palloc.addr1 < r->start && r->start <= conf.base1+(conf.npage1<<PGSHIFT))
- palloc.addr1 = r->start;
-
- /*
- * zero it
- */
- memset((void*)(p|KZERO), 0, n);
- return (void*)(p|KZERO);
-}
-
-/*
- * allocate with possible page alignment
- */
-void*
-ialloc(ulong n, int align)
-{
- return iallocspan(n, align ? BY2PG : 0, 0);
-}
+static Lock pglock;
+struct Palloc palloc;
void
pageinit(void)
{
- ulong np, addr, lim;
- ulong i, vmem, pmem, hw, hr;
Page *p;
+ ulong np, hw, hr, vmem, pmem;
+
+ np = palloc.np0+palloc.np1;
+ palloc.head = xalloc(np*sizeof(Page));
+ if(palloc.head == 0)
+ panic("pageinit");
- /*
- * calculate an upper bound to the number of pages structures
- * we'll need (np).
- */
- np = (conf.npage0<<PGSHIFT) - (palloc.addr0 - conf.base0);
- np += (conf.npage1<<PGSHIFT) - (palloc.addr1 - conf.base1);
- np = np>>PGSHIFT;
-
- /*
- * allocate Page structs (no more ialloc's allowed after this).
- * np is useless after this ialloc since we've just eaten up
- * some pages for the Page structures.
- */
- palloc.head = ialloc(np*sizeof(Page), 0);
- palloc.active = 1;
-
- /*
- * for each page in each bank, point a page structure to
- * the page and chain it into the free list
- */
p = palloc.head;
- addr = palloc.addr0 = PGROUND(palloc.addr0);
- lim = conf.base0 + (conf.npage0<<PGSHIFT);
- for(; addr < lim; addr += BY2PG){
- p->next = p+1;
+ while(palloc.np0 > 0) {
p->prev = p-1;
- p->pa = addr;
+ p->next = p+1;
+ p->pa = palloc.p0;
+ palloc.p0 += BY2PG;
+ palloc.np0--;
p++;
}
- addr = palloc.addr1 = PGROUND(palloc.addr1);
- lim = conf.base1 + (conf.npage1<<PGSHIFT);
- for(; addr < lim; addr += BY2PG){
- p->next = p+1;
+ while(palloc.np1 > 0) {
p->prev = p-1;
- p->pa = addr;
+ p->next = p+1;
+ p->pa = palloc.p1;
+ palloc.p1 += BY2PG;
+ palloc.np1--;
p++;
}
palloc.tail = p - 1;
palloc.head->prev = 0;
palloc.tail->next = 0;
- palloc.user = palloc.freecount = p - palloc.head;
+ palloc.user = p - palloc.head;
+ palloc.freecount = palloc.user;
pmem = palloc.user*BY2PG/1024;
- vmem = pmem + ((conf.nswap)*BY2PG)/1024;
+ vmem = pmem + (conf.nswap*BY2PG)/1024;
/* Pageing numbers */
swapalloc.highwater = (palloc.freecount*5)/100;
swapalloc.headroom = swapalloc.highwater + (swapalloc.highwater/4);
- hw = (swapalloc.highwater*BY2PG)/1024;
- hr = (swapalloc.headroom*BY2PG)/1024;
+
+ hw = swapalloc.highwater*BY2PG;
+ hr = swapalloc.headroom*BY2PG;
- print("%lud free pages, %dK bytes, swap %dK bytes, highwater %dK, headroom %dK\n",
- palloc.user, pmem, vmem, hw, hr);
+ print("%lud free pages, %dK bytes, swap %dK, highwater %dK, headroom %dK\n",
+ palloc.user, pmem, vmem, hw/1024, hr/1024);
}
Page*
@@ 260,13 73,11 @@ newpage(int clear, Segment **s, ulong va)
KMap *k;
int i;
- if(palloc.active == 0)
- print("newpage inactive\n");
-
lock(&palloc);
/* The kp test is a poor guard against the pager deadlocking */
- while((palloc.freecount < swapalloc.highwater && u->p->kp == 0)||palloc.freecount == 0) {
+ while((palloc.freecount < swapalloc.highwater && u->p->kp == 0) ||
+ palloc.freecount == 0) {
palloc.wanted++;
unlock(&palloc);
if(s && *s) {
@@ 605,3 416,32 @@ freepte(Segment *s, Pte *p)
ptealloclk.free = p;
unlock(&ptealloclk);
}
+
+/* Multiplex a hardware lock for per page manipulations */
+void
+lockpage(Page *p)
+{
+ int s;
+
+ for(;;) {
+ if(p->lock == 0) {
+ s = splhi();
+ lock(&pglock);
+ if(p->lock == 0) {
+ p->lock = 1;
+ unlock(&pglock);
+ splx(s);
+ return;
+ }
+ unlock(&pglock);
+ splx(s);
+ }
+ sched();
+ }
+}
+
+void
+unlockpage(Page *p)
+{
+ p->lock = 0;
+}
M port/pgrp.c => port/pgrp.c +32 -192
@@ 5,73 5,8 @@
#include "fns.h"
#include "../port/error.h"
-Pgrps pgrpalloc;
-
-struct
-{
- Lock;
- Egrp *free;
-}egrpalloc;
-
-struct
-{
- Lock;
- Fgrp *free;
-}fgrpalloc;
-
-struct{
- Lock;
- Mount *free;
- Mhead *mhfree;
- ulong mountid;
-}mountalloc;
-
-void
-grpinit(void)
-{
- int i;
- Pgrp *p;
- Egrp *e, *ee;
- Fgrp *f, *fe;
- Mount *m, *em;
- Mhead *hm, *hem;
- Crypt *cr;
-
- i = conf.npgrp*sizeof(Crypt);
- cr = ialloc(i, 0);
- pgrpalloc.cryptbase = (ulong)cr;
- pgrpalloc.crypttop = (ulong)cr + i;
- pgrpalloc.arena = ialloc(conf.npgrp*sizeof(Pgrp), 0);
- pgrpalloc.free = pgrpalloc.arena;
-
- p = pgrpalloc.free;
- for(i=0; i<conf.npgrp; i++,p++) {
- p->index = i;
- p->next = p+1;
- p->crypt = cr++;
- }
- p[-1].next = 0;
-
- egrpalloc.free = ialloc(conf.npgrp*sizeof(Egrp), 0);
- ee = &egrpalloc.free[conf.npgrp];
- for(e = egrpalloc.free; e < ee; e++) {
- e->next = e+1;
- e->etab = ialloc(conf.npgenv*sizeof(Env), 0);
- }
- e[-1].next = 0;
-
- fgrpalloc.free = ialloc(conf.nproc*sizeof(Fgrp), 0);
- fe = &fgrpalloc.free[conf.nproc-1];
- for(f = fgrpalloc.free; f < fe; f++)
- f->next = f+1;
- f->next = 0;
-}
-
-Pgrp*
-pgrptab(int i)
-{
- return &pgrpalloc.arena[i];
-}
+static Ref pgrpid;
+static Ref mountid;
void
pgrpnote(ulong noteid, char *a, long n, int flag)
@@ 109,22 44,12 @@ newpgrp(void)
{
Pgrp *p;
- for(;;) {
- lock(&pgrpalloc);
- if(p = pgrpalloc.free){
- pgrpalloc.free = p->next;
- p->ref = 1;
- p->pgrpid = ++pgrpalloc.pgrpid;
- memset(p->crypt, 0, sizeof *p->crypt);
- memset(p->rendhash, 0, sizeof(p->rendhash));
- memset(p->mnthash, 0, sizeof(p->mnthash));
- unlock(&pgrpalloc);
- return p;
- }
- unlock(&pgrpalloc);
- resrcwait("no pgrps");
- }
- return 0; /* not reached */
+ p = smalloc(sizeof(Pgrp)+sizeof(Crypt));
+ p->ref = 1;
+ /* This needs to have its own arena for protection */
+ p->crypt = (Crypt*)((uchar*)p+sizeof(Pgrp));
+ p->pgrpid = incref(&pgrpid);
+ return p;
}
Egrp*
@@ 132,19 57,12 @@ newegrp(void)
{
Egrp *e;
- for(;;) {
- lock(&egrpalloc);
- if(e = egrpalloc.free) {
- egrpalloc.free = e->next;
- e->ref = 1;
- e->nenv = 0;
- unlock(&egrpalloc);
- return e;
- }
- unlock(&egrpalloc);
- resrcwait("no envgrps");
- }
- return 0; /* not reached */
+ e = smalloc(sizeof(Egrp)+sizeof(Env)*conf.npgenv);
+
+ /* This is a sleazy hack to make malloc work .. devenv need rewriting. */
+ e->etab = (Env*)((uchar*)e+sizeof(Egrp));
+ e->ref = 1;
+ return e;
}
Fgrp*
@@ 152,20 70,9 @@ newfgrp(void)
{
Fgrp *f;
- for(;;) {
- lock(&fgrpalloc);
- if(f = fgrpalloc.free) {
- fgrpalloc.free = f->next;
- f->ref = 1;
- f->maxfd = 0;
- memset(f->fd, 0, sizeof(f->fd));
- unlock(&fgrpalloc);
- return f;
- }
- unlock(&fgrpalloc);
- resrcwait("no filegrps");
- }
- return 0; /* not reached */
+ f = smalloc(sizeof(Fgrp));
+ f->ref = 1;
+ return f;
}
Fgrp*
@@ 221,15 128,11 @@ closepgrp(Pgrp *p)
close(f->from);
mountfree(f->mount);
next = f->hash;
- mntheadfree(f);
+ free(f);
}
}
-
- lock(&pgrpalloc);
- p->next = pgrpalloc.free;
- pgrpalloc.free = p;
qunlock(&p->debug);
- unlock(&pgrpalloc);
+ free(p);
}
}
@@ 243,10 146,8 @@ closeegrp(Egrp *eg)
e = eg->etab;
for(i=0; i<eg->nenv; i++, e++)
envpgclose(e);
- lock(&egrpalloc);
- eg->next = egrpalloc.free;
- egrpalloc.free = eg;
- unlock(&egrpalloc);
+
+ free(eg);
}
}
@@ 261,10 162,7 @@ closefgrp(Fgrp *f)
if(c = f->fd[i])
close(c);
- lock(&fgrpalloc);
- f->next = fgrpalloc.free;
- fgrpalloc.free = f;
- unlock(&fgrpalloc);
+ free(f);
}
}
@@ 274,31 172,12 @@ newmount(Mhead *mh, Chan *to)
{
Mount *m, *f, *e;
- for(;;) {
- lock(&mountalloc);
- if(m = mountalloc.free){ /* assign = */
- mountalloc.free = m->next;
- m->mountid = ++mountalloc.mountid;
- unlock(&mountalloc);
- m->next = 0;
- m->head = mh;
- m->to = to;
- incref(to);
- return m;
- }
- unlock(&mountalloc);
-
- m = (Mount*)VA(kmap(newpage(0, 0, 0)));
- e = &m[(BY2PG/sizeof(Mount))-1];
- for(f = m; f < e; f++)
- f->next = f+1;
-
- lock(&mountalloc);
- e->next = mountalloc.free;
- mountalloc.free = m;
- unlock(&mountalloc);
- }
- return 0; /* not reached */
+ m = smalloc(sizeof(Mount));
+ m->to = to;
+ m->head = mh;
+ incref(to);
+ m->mountid = incref(&mountid);
+ return m;
}
void
@@ 331,7 210,7 @@ pgrpcpy(Pgrp *to, Pgrp *from)
for(h = from->mnthash; h < e; h++) {
l = tom++;
for(f = *h; f; f = f->hash) {
- mh = newmnthead();
+ mh = smalloc(sizeof(Mhead));
mh->from = f->from;
incref(mh->from);
*l = mh;
@@ 347,44 226,6 @@ pgrpcpy(Pgrp *to, Pgrp *from)
runlock(&from->ns);
}
-Mhead *
-newmnthead(void)
-{
- Mhead *mh, *f, *e;
-
- for(;;) {
- lock(&mountalloc);
- if(mh = mountalloc.mhfree) { /* Assign '=' */
- mountalloc.mhfree = mh->hash;
- unlock(&mountalloc);
- mh->hash = 0;
- mh->mount = 0;
- return mh;
- }
- unlock(&mountalloc);
-
- mh = (Mhead*)VA(kmap(newpage(0, 0, 0)));
- e = &mh[(BY2PG/sizeof(Mhead))-1];
- for(f = mh; f < e; f++)
- f->hash = f+1;
-
- lock(&mountalloc);
- e->hash = mountalloc.mhfree;
- mountalloc.mhfree = mh;
- unlock(&mountalloc);
- }
- return 0; /* not reached */
-}
-
-void
-mntheadfree(Mhead *mh)
-{
- lock(&mountalloc);
- mh->hash = mountalloc.mhfree;
- mountalloc.mhfree = mh;
- unlock(&mountalloc);
-}
-
void
mountfree(Mount *m)
{
@@ 392,9 233,8 @@ mountfree(Mount *m)
for(f = m; f->next; f = f->next)
close(f->to);
+
close(f->to);
- lock(&mountalloc);
- f->next = mountalloc.free;
- mountalloc.free = m;
- unlock(&mountalloc);
+
+ free(f);
}
M port/portdat.h => port/portdat.h +4 -5
@@ 38,6 38,8 @@ typedef struct Talarm Talarm;
typedef struct Waitq Waitq;
typedef int Devgen(Chan*, Dirtab*, int, int, Dir*);
+#include "fcall.h"
+
struct List
{
void *next;
@@ 394,7 396,6 @@ struct Pgrp
struct Egrp
{
Ref;
- Egrp *next;
int nenv; /* highest active env table entry, +1 */
QLock ev; /* for all of etab */
Env *etab;
@@ 404,7 405,6 @@ struct Egrp
struct Fgrp
{
Ref;
- Fgrp *next;
Chan *fd[NFD];
int maxfd; /* highest fd in use */
};
@@ 413,9 413,8 @@ struct Fgrp
struct Palloc
{
Lock;
- ulong addr0; /* next available ialloc addr in bank 0 */
- ulong addr1; /* next available ialloc addr in bank 1 */
- int active;
+ ulong p0, p1; /* base of pages in bank 0/1 */
+ ulong np0, np1; /* number of pages in bank 0/1 */
Page *head; /* most recently used */
Page *tail; /* least recently used */
ulong freecount; /* how many pages on free list now */
M port/portfns.h => port/portfns.h +8 -4
@@ 84,7 84,6 @@ Block* getq(Queue*);
int gets(IOQ*, void*, int);
void gotolabel(Label*);
Block* grabq(Queue*);
-void grpinit(void);
int hwcursmove(int, int);
int hwcursset(uchar*, uchar*, int, int);
void* ialloc(ulong, int);
@@ 232,7 231,6 @@ long streamwrite(Chan*, void*, long, int);
long stringread(void*, long, char*, ulong);
void swapinit(void);
long syscall(Ureg*);
-void tcpinit(void);
void tsleep(Rendez*, int (*)(void*), void*, int);
void uncachepage(Page*);
long unionread(Chan*, void*, long);
@@ 248,8 246,14 @@ void rlock(RWlock*);
void runlock(RWlock*);
void wlock(RWlock*);
void wunlock(RWlock*);
-Mhead* newmnthead(void);
void mountfree(Mount*);
-void mntheadfree(Mhead*);
void unmount(Chan*, Chan*);
void urpfillstats(Chan*, char*, int);
+void xinit(void);
+void *xalloc(ulong);
+void xfree(void*);
+void xhole(ulong, ulong);
+void xsummary(void);
+void *malloc(ulong);
+void *smalloc(ulong);
+void free(void*);
M port/proc.c => port/proc.c +3 -2
@@ 62,7 62,8 @@ schedinit(void) /* never returns */
u = 0;
if(p->state == Running)
ready(p);
- else if(p->state == Moribund) {
+ else
+ if(p->state == Moribund) {
p->pid = 0;
/*
* Holding locks from pexit:
@@ 244,7 245,7 @@ procinit0(void) /* bad planning - clashes with devproc.c */
Proc *p;
int i;
- procalloc.free = ialloc(conf.nproc*sizeof(Proc), 0);
+ procalloc.free = xalloc(conf.nproc*sizeof(Proc));
procalloc.arena = procalloc.free;
p = procalloc.free;
M port/segment.c => port/segment.c +13 -48
@@ 22,12 22,6 @@ struct Imagealloc
Image *hash[IHASHSIZE];
}imagealloc;
-struct segalloc
-{
- Lock;
- Segment *free;
-}segalloc;
-
static QLock ireclaim;
void
@@ 36,14 30,7 @@ initseg(void)
Segment *s, *se;
Image *i, *ie;
- segalloc.free = ialloc(conf.nseg*sizeof(Segment), 0);
- imagealloc.free = ialloc(conf.nimage*sizeof(Image), 0);
-
- se = &segalloc.free[conf.nseg-1];
- for(s = segalloc.free; s < se; s++)
- s->next = s+1;
- s->next = 0;
-
+ imagealloc.free = xalloc(conf.nimage*sizeof(Image));
ie = &imagealloc.free[conf.nimage-1];
for(i = imagealloc.free; i < ie; i++)
i->next = i+1;
@@ 58,32 45,13 @@ newseg(int type, ulong base, ulong size)
if(size > (SEGMAPSIZE*PTEPERTAB))
error(Enovmem);
- for(;;) {
- lock(&segalloc);
- if(s = segalloc.free) {
- segalloc.free = s->next;
- unlock(&segalloc);
-
- s->ref = 1;
- s->steal = 0;
- s->type = type;
- s->base = base;
- s->top = base+(size*BY2PG);
- s->size = size;
- s->image = 0;
- s->fstart = 0;
- s->flen = 0;
- s->pgalloc = 0;
- s->pgfree = 0;
- s->flushme = 0;
- memset(s->map, 0, sizeof(s->map));
-
- return s;
- }
- unlock(&segalloc);
- resrcwait("no segments");
- }
- return 0; /* not reached */
+ s = smalloc(sizeof(Segment));
+ s->ref = 1;
+ s->type = type;
+ s->base = base;
+ s->top = base+(size*BY2PG);
+ s->size = size;
+ return s;
}
void
@@ 117,10 85,7 @@ putseg(Segment *s)
qunlock(&s->lk);
- lock(&segalloc);
- s->next = segalloc.free;
- segalloc.free = s;
- unlock(&segalloc);
+ free(s);
}
}
@@ 237,10 202,10 @@ attachimage(int type, Chan *c, ulong base, ulong len)
for(i = ihash(c->qid.path); i; i = i->hash) {
if(c->qid.path == i->qid.path) {
lock(i);
- if(eqqid(c->qid, i->qid))
- if(eqqid(c->mqid, i->mqid))
- if(c->mchan == i->mchan)
- if(c->type == i->type) {
+ if(eqqid(c->qid, i->qid) &&
+ eqqid(c->mqid, i->mqid) &&
+ c->mchan == i->mchan &&
+ c->type == i->type) {
i->ref++;
goto found;
}
M port/stfcall.c => port/stfcall.c +0 -2
@@ 5,8 5,6 @@
#include "fns.h"
#include "../port/error.h"
-#include "fcall.h"
-
enum
{
Twritehdr = 15, /* Min bytes for Twrite */
M port/stream.c => port/stream.c +18 -162
@@ 6,7 6,6 @@
#include "io.h"
#include "../port/error.h"
#include "devtab.h"
-#include "fcall.h"
enum {
Nclass=4, /* number of block classes */
@@ 30,31 29,11 @@ Qinfo procinfo =
*/
static Qinfo *lds;
-/*
- * All stream structures are ialloc'd at boot time
- */
Stream *slist;
Queue *qlist;
static Lock garbagelock;
/*
- * The block classes. There are Nclass block sizes, each with its own free list.
- * All are ialloced at qinit() time.
- */
-typedef struct {
- int size;
- int made;
- QLock;
- Blist;
-} Bclass;
-Bclass bclass[Nclass]={
- { 0 },
- { 68 },
- { 268 },
- { 4096 },
-};
-
-/*
* Allocate streams, queues, and blocks. Allocate n block classes with
* 1/2(m+1) to class m < n-1
* 1/2(n-1) to class n-1
@@ 62,25 41,12 @@ Bclass bclass[Nclass]={
void
streaminit(void)
{
- int class, i, n;
- Bclass *bcp;
/*
* allocate queues, streams
*/
- slist = (Stream *)ialloc(conf.nstream * sizeof(Stream), 0);
- qlist = (Queue *)ialloc(conf.nqueue * sizeof(Queue), 0);
-
- /*
- * set block classes
- */
- n = conf.nblock;
- for(class = 0; class < Nclass; class++){
- if(class < Nclass-1)
- n = n/2;
- bcp = &bclass[class];
- bcp->made = 0;
- }
+ slist = (Stream *)xalloc(conf.nstream * sizeof(Stream));
+ qlist = (Queue *)xalloc(conf.nqueue * sizeof(Queue));
/*
* make stream modules available
@@ 105,107 71,22 @@ newqinfo(Qinfo *qi)
}
/*
- * upgrade a block 0 block to another class (called with bcp qlocked)
- */
-int
-newblock(Bclass *bcp)
-{
- Page *page;
- int n;
- Block *bp;
- uchar *cp;
-
- page = newpage(1, 0, 0);
- page->va = VA(kmapperm(page));
- if(bcp == bclass){
- /*
- * create some level zero blocks and return
- */
- n = BY2PG/sizeof(Block);
- bp = (Block *)(page->va);
- while(n-- > 0){
- bp->flags = 0;
- bp->base = bp->lim = bp->rptr = bp->wptr = 0;
- if(bcp->first)
- bcp->last->next = bp;
- else
- bcp->first = bp;
- bcp->last = bp;
- bcp->made++;
- bp++;
- }
- } else {
- /*
- * create a page worth of new blocks
- */
- n = BY2PG/bcp->size;
- cp = (uchar *)(page->va);
-
- while(n-- > 0){
- /*
- * upgrade a level 0 block
- */
- bp = allocb(0);
- qlock(bclass);
- bclass->made--;
- bcp->made++;
- bp->flags = bcp - bclass;
- qunlock(bclass);
-
- /*
- * tack on the data area
- */
- bp->base = bp->rptr = bp->wptr = cp;
- cp += bcp->size;
- bp->lim = cp;
- if(bcp->first)
- bcp->last->next = bp;
- else
- bcp->first = bp;
- bcp->last = bp;
- }
- }
- return 0;
-}
-
-/*
* allocate a block
*/
Block *
allocb(ulong size)
{
Block *bp;
- Bclass *bcp;
+ uchar *data;
- /*
- * map size to class
- */
- for(bcp=bclass; bcp->size<size && bcp<&bclass[Nclass-1]; bcp++)
- ;
+ bp = smalloc(sizeof(Block)+size);
- /*
- * look for a free block
- */
- qlock(bcp);
- while(bcp->first == 0){
- if(waserror()){
- qunlock(bcp);
- nexterror();
- }
- newblock(bcp);
- poperror();
- }
- bp = bcp->first;
- bcp->first = bp->next;
- if(bcp->first == 0)
- bcp->last = 0;
- qunlock(bcp);
-
- /*
- * return an empty block
- */
- bp->flags = bcp - bclass;
- bp->rptr = bp->wptr = bp->base;
+ data = (uchar*)bp + sizeof(Block);
+ bp->rptr = data;
+ bp->wptr = data;
+ bp->base = data;
+ bp->lim = data+size;
+ bp->flags = 0;
bp->next = 0;
bp->list = 0;
bp->type = M_DATA;
@@ 219,31 100,14 @@ allocb(ulong size)
void
freeb(Block *bp)
{
- ulong mark[1];
- Block *nbp;
- Bclass *bcp;
- int x;
- ulong pc;
-
-#ifdef asdf
- pc = getcallerpc(((uchar*)&bp) - sizeof(bp));
- if((bp->flags&S_CLASS) >= Nclass) /* Check for double free */
- panic("freeb class last(%lux) this(%lux)", bp->pc, pc);
- bp->pc = pc;
-#endif asdf
- for(; bp; bp = nbp){
- bcp = &bclass[bp->flags & S_CLASS];
- bp->flags = bp->flags|S_CLASS; /* Check for double free */
- qlock(bcp);
- bp->rptr = bp->wptr = 0;
- if(bcp->first)
- bcp->last->next = bp;
- else
- bcp->first = bp;
- bcp->last = bp;
- nbp = bp->next;
- bp->next = 0;
- qunlock(bcp);
+ Block *next;
+
+ while(bp){
+ bp->rptr = 0;
+ bp->wptr = 0;
+ next = bp->next;
+ free(bp);
+ bp = next;
}
}
@@ 1497,7 1361,6 @@ dumpqueues(void)
Queue *q;
int count, qcount;
Block *bp;
- Bclass *bcp;
print("\n");
qcount = 0;
@@ 1516,11 1379,4 @@ dumpqueues(void)
dumpblocks(WR(q), 'W');
}
print("%d queues\n", qcount);
- for(bcp=bclass; bcp<&bclass[Nclass]; bcp++){
- for(count = 0, bp = bcp->first; bp; count++, bp = bp->next)
- ;
- print("%d byte blocks: %d made %d free\n", bcp->size,
- bcp->made, count);
- }
- print("\n");
}
M port/swap.c => port/swap.c +1 -1
@@ 26,7 26,7 @@ int ioptr;
void
swapinit(void)
{
- swapalloc.swmap = ialloc(conf.nswap, 0);
+ swapalloc.swmap = xalloc(conf.nswap);
swapalloc.top = &swapalloc.swmap[conf.nswap];
swapalloc.alloc = swapalloc.swmap;
M port/sysfile.c => port/sysfile.c +0 -1
@@ 4,7 4,6 @@
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
-#include "fcall.h"
/*
* The sys*() routines needn't poperror() as they return directly to syscall().
M port/tcpinput.c => port/tcpinput.c +4 -36
@@ 11,27 11,12 @@ int tcpdbg = 0;
#define DPRINT if(tcpdbg) print
#define LPRINT if(tcpdbg) print
-QLock reseqlock;
-Reseq *reseqfree;
-
char *tcpstate[] = {
"Closed", "Listen", "Syn_sent", "Syn_received",
"Established", "Finwait1", "Finwait2", "Close_wait",
"Closing", "Last_ack", "Time_wait" };
void
-tcpinit(void)
-{
- Reseq *r;
-
- reseqfree = ialloc(sizeof(Reseq)*Nreseq, 0);
- for(r = reseqfree; r < &reseqfree[Nreseq-1]; r++)
- r->next = r+1;
-
- r->next = 0;
-}
-
-void
reset(Ipaddr source, Ipaddr dest, char tos, ushort length, Tcp *seg)
{
Block *hbp;
@@ 624,20 609,10 @@ void
add_reseq(Tcpctl *tcb, char tos, Tcp *seg, Block *bp, ushort length)
{
Reseq *rp, *rp1;
- static int dropped;
- qlock(&reseqlock);
- if(!reseqfree) {
- qunlock(&reseqlock);
- if((dropped++%256) == 0)
- print("tcp: no resequence descriptors\n");
- freeb(bp);
+ rp = malloc(sizeof(Reseq));
+ if(rp == 0)
return;
- }
-
- rp = reseqfree;
- reseqfree = rp->next;
- qunlock(&reseqlock);
rp->seg = *seg;
rp->tos = tos;
@@ 677,10 652,7 @@ get_reseq(Tcpctl *tcb, char *tos, Tcp *seg, Block **bp, ushort *length)
*bp = rp->bp;
*length = rp->length;
- qlock(&reseqlock);
- rp->next = reseqfree;
- reseqfree = rp;
- qunlock(&reseqlock);
+ free(rp);
}
int
@@ 874,11 846,7 @@ close_self(Ipconv *s, char reason[])
for(rp = tcb->reseq;rp != 0;rp = rp1){
rp1 = rp->next;
freeb(rp->bp);
-
- qlock(&reseqlock);
- rp->next = reseqfree;
- reseqfree = rp;
- qunlock(&reseqlock);
+ free(rp);
}
tcb->reseq = 0;
M ss/dat.h => ss/dat.h +1 -1
@@ 69,6 69,7 @@ struct Conf
ulong nimage; /* number of page cache image headers */
ulong npagetab; /* number of pte tables */
ulong nswap; /* number of swap blocks */
+ ulong upages; /* number of user pages */
int nalarm; /* alarms */
int nchan; /* channels */
int nenv; /* distinct environment values */
@@ 92,7 93,6 @@ struct Conf
int npipe; /* number of pipes */
int nservice; /* number of services */
int nfsyschan; /* number of filsys open channels */
- ulong maxialloc; /* maximum bytes used by ialloc */
int copymode; /* 0 is copy on write, 1 is copy on reference */
ulong ipif; /* Ip protocol interfaces */
ulong ip; /* Ip conversations per interface */
M ss/fns.h => ss/fns.h +2 -0
@@ 23,6 23,8 @@ int kbdstate(IOQ*, int);
void kbdclock(void);
void kbdrepeat(int);
KMap* kmap(Page*);
+#define KADDR(a) ((void*)((ulong)(a)|KZERO))
+#define PADDR(a) ((ulong)(a)&~KZERO)
void kmapinit(void);
KMap* kmappa(ulong, ulong);
KMap* kmapperm(Page*);
M ss/main.c => ss/main.c +6 -4
@@ 23,10 23,11 @@ main(void)
active.exiting = 0;
active.machs = 1;
confinit();
+ xinit();
mmuinit();
screeninit();
printinit();
- print("sparc plan 9\n");
+ pageinit();
trapinit();
kmapinit();
ioinit();
@@ 34,11 35,9 @@ main(void)
intrinit();
procinit0();
initseg();
- grpinit();
chaninit();
chandevreset();
streaminit();
- pageinit();
userinit();
clockinit();
schedinit();
@@ 198,12 197,15 @@ confinit(void)
conf.nmach = 1;
if(conf.nmach > MAXMACH)
panic("confinit");
+
conf.npage0 = (4*1024*1024)/BY2PG; /* BUG */
conf.npage1 = (4*1024*1024)/BY2PG; /* BUG */
conf.base0 = 0;
conf.base1 = 32*1024*1024;
conf.npage = conf.npage0+conf.npage1;
- conf.maxialloc = 4*1024*1024; /* BUG */
+
+ conf.upages = 1400;
+
mul = 1;
if(conf.npage1 > 0)
mul = 2;
M ss/mmu.c => ss/mmu.c +13 -5
@@ 136,25 136,31 @@ purgepid(int pid)
flushcontext();
}
-
void
mmuinit(void)
{
- ulong l, i, j, c, pte;
+ ulong ktop, l, i, j, c, pte;
/*
+ * TEMP: just map the first 4M of bank 0 for the kernel - philw
+ */
+ ktop = 4*1024*1024;
+ /*
* First map lots of memory as kernel addressable in all contexts
*/
i = 0; /* used */
for(c=0; c<NCONTEXT; c++)
- for(i=0; i<conf.maxialloc/BY2SEGM; i++)
+ for(i=0; i < ktop/BY2SEGM; i++)
putcxsegm(c, KZERO+i*BY2SEGM, i);
+
kmapalloc.lowpmeg = i;
+
/*
* Make sure cache is turned on for kernel
*/
pte = PTEVALID|PTEWRITE|PTEKERNEL|PTEMAINMEM;
- for(i=0; i<conf.maxialloc/BY2PG; i++)
+ ktop /= BY2PG;
+ for(i=0; i < ktop; i++)
putpmeg(KZERO+i*BY2PG, pte+i);
/*
@@ 163,6 169,7 @@ mmuinit(void)
putsegm(INVALIDSEGM, INVALIDPMEG);
for(i=0; i<PG2SEGM; i++)
putpmeg(INVALIDSEGM+i*BY2PG, INVALIDPTE);
+
for(c=0; c<NCONTEXT; c++){
putcontext(c);
putsegm(INVALIDSEGM, INVALIDPMEG);
@@ 317,7 324,8 @@ kmapinit(void)
KMap *k;
int i;
-print("low pmeg %d high pmeg %d\n", kmapalloc.lowpmeg, TOPPMEG);
+ print("low pmeg %d high pmeg %d\n", kmapalloc.lowpmeg, TOPPMEG);
+
kmapalloc.free = 0;
k = kmapalloc.arena;
for(i=0; i<(IOEND-IOSEGM)/BY2PG; i++,k++){