A port/alloc.c => port/alloc.c +150 -0
@@ 0,0 1,150 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#define nil ((void*)0)
+#define datoff ((int)&((Xhdr*)0)->data)
+
+enum
+{
+ Nhole = 128,
+ Magic = 0xDeadBabe,
+};
+
+typedef struct Hole Hole;
+typedef struct Xalloc Xalloc;
+typedef struct Xhdr Xhdr;
+struct Hole
+{
+ ulong addr;
+ ulong size;
+ ulong top;
+ Hole *link;
+};
+
+struct Xhdr
+{
+ ulong size;
+ ulong magix;
+ char data[1];
+};
+
+struct Xalloc
+{
+ Lock;
+ Hole hole[Nhole];
+ Hole *flist;
+ Hole *table;
+};
+
+Xalloc xlists;
+
+void
+xinit(void)
+{
+ Hole *h, *eh;
+
+ eh = &xlists.hole[Nhole-1];
+ for(h = xlists.hole; h < eh; h++)
+ h->link = h+1;
+
+ xlists.flist = h;
+}
+
+void
+xhole(ulong addr, ulong size)
+{
+ Hole *h, **l;
+
+ 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;
+ }
+
+ if(xlists.flist == nil) {
+ print("xfree: no free holes, leaked %d bytes\n", size);
+ unlock(&xlists);
+ return;
+ }
+
+ h = xlists.flist;
+ xlists.flist = h->link;
+ h->addr = addr;
+ h->top = addr+size;
+ h->size = size;
+ h->link = *l;
+ *l = h;
+ unlock(&xlists);
+}
+
+void*
+xalloc(ulong size)
+{
+ Hole *h, **l;
+ Xhdr *p;
+
+ size += sizeof(Xhdr);
+
+ lock(&xlists);
+ l = &xlists.table;
+ for(h = *l; h; h = h->link) {
+ if(h->size >= size) {
+ p = (Xhdr*)h->addr;
+ h->addr += size;
+ h->size -= size;
+ if(h->size == 0) {
+ *l = h->link;
+ h->link = xlists.flist;
+ xlists.flist = h;
+ }
+ p->magix = Magic;
+ p->size = size;
+ unlock(&xlists);
+ return p->data;
+ }
+ l = &h->link;
+ }
+ unlock(&xlists);
+ return nil;
+}
+
+void
+xfree(void *p)
+{
+ Xhdr *x;
+
+ x = (Xhdr*)((ulong)p - datoff);
+ if(x->magix != Magic)
+ panic("xfree");
+
+ xhole((ulong)x, x->size);
+}
+
+void
+xsummary(void)
+{
+ int i;
+ Hole *h;
+
+ i = 0;
+ for(h = xlists.flist; h; h = h->link)
+ i++;
+
+ 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);
+ i += h->size;
+ }
+ print("%d bytes free\n", i);
+}
M port/malloc.c => port/malloc.c +11 -12
@@ 4,7 4,7 @@
enum
{
MAGIC = 0xDEADBABE,
- MAX2SIZE = 20
+ MAXPOW = 20
};
typedef struct Bucket Bucket;
@@ 20,9 20,8 @@ typedef struct Arena Arena;
struct Arena
{
Lock;
- Bucket *btab[MAX2SIZE];
+ Bucket *btab[MAXPOW];
};
-
static Arena arena;
#define datoff ((int)&((Bucket*)0)->data)
@@ 32,14 31,15 @@ malloc(uint size)
int pow;
Bucket *bp;
- for(pow = 1; pow < MAX2SIZE; pow++) {
+ size += sizeof(Bucket);
+
+ for(pow = 1; pow < MAXPOW; pow++)
if(size <= (1<<pow))
goto good;
- }
- return nil;
+ return 0;
+
good:
- /* Allocate off this list */
lock(&arena);
bp = arena.btab[pow];
if(bp) {
@@ 47,7 47,7 @@ good:
arena.unlock();
if(bp->magic != 0)
- abort();
+ panic("malloc");
bp->magic = MAGIC;
@@ 55,14 55,13 @@ good:
return bp->data;
}
unlock(&arena);
+
size = sizeof(Bucket)+(1<<pow);
- bp = sbrk(size);
+ bp = xbrk(size);
if((int)bp < 0)
return nil;
- bp->size = pow;
- bp->magic = MAGIC;
-
+ memset(bp->data, 0, size);
return bp->data;
}
M port/page.c => port/page.c +14 -10
@@ 66,11 66,14 @@ Region region[Nregion];
void
addsplit(Region *r, ulong start, ulong end)
{
- Region *rr;
- int len = end - start;
+ int len;
+ Region *rr, *eregion;
+
+ len = end - start;
+ eregion = ®ion[Nregion];
/* first look for an unused one */
- for(rr = region; rr < ®ion[Nregion]; rr++){
+ for(rr = region; rr < eregion; rr++){
if(rr == r)
continue;
if(rr->end - rr->start == 0){
@@ 81,7 84,7 @@ addsplit(Region *r, ulong start, ulong end)
}
/* then look for a smaller one */
- for(rr = region; rr < ®ion[Nregion]; rr++){
+ for(rr = region; rr < eregion; rr++){
if(rr == r)
continue;
if(rr->end - rr->start < len){
@@ 105,19 108,21 @@ addsplit(Region *r, ulong start, ulong end)
void*
iallocspan(ulong n, int align, ulong crevasse)
{
+ int m;
ulong p;
Region *r;
- int m;
int ledge;
if(palloc.active && n!=0)
print("ialloc bad\n");
if(palloc.addr0 == 0){
- region[Nregion-2].start = (((ulong)end)&~KZERO) + conf.base0;
- region[Nregion-2].end = conf.base0 + (conf.npage0<<PGSHIFT);
- region[Nregion-1].start = conf.base1;
- region[Nregion-1].end = conf.base1 + (conf.npage1<<PGSHIFT);
+ 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;
@@ 174,7 179,6 @@ iallocspan(ulong n, int align, ulong crevasse)
* zero it
*/
memset((void*)(p|KZERO), 0, n);
-
return (void*)(p|KZERO);
}
M power/devcyc.c => power/devcyc.c +0 -1
@@ 204,7 204,6 @@ cycclose(Chan *c)
}
}
-
int
cycmsgintr(Cycmsg *hm)
{