--- /n/sources/plan9/sys/include/libc.h Wed Sep 18 22:45:28 2013 +++ /sys/include/libc.h Sun Jun 28 00:00:00 2026 @@ -109,17 +109,17 @@ extern int isupperrune(Rune); /* * malloc */ -extern void* malloc(ulong); -extern void* mallocz(ulong, int); +extern void* malloc(uintptr); +extern void* mallocz(uintptr, int); extern void free(void*); -extern ulong msize(void*); -extern void* mallocalign(ulong, ulong, long, ulong); -extern void* calloc(ulong, ulong); -extern void* realloc(void*, ulong); -extern void setmalloctag(void*, ulong); -extern void setrealloctag(void*, ulong); -extern ulong getmalloctag(void*); -extern ulong getrealloctag(void*); +extern uintptr msize(void*); +extern void* mallocalign(uintptr, uintptr, vlong, uintptr); +extern void* calloc(uintptr, uintptr); +extern void* realloc(void*, uintptr); +extern void setmalloctag(void*, uintptr); +extern void setrealloctag(void*, uintptr); +extern uintptr getmalloctag(void*); +extern uintptr getrealloctag(void*); extern void* malloctopoolblock(void*); /* --- /n/sources/plan9/sys/include/pool.h Sat Jan 10 10:00:05 2015 +++ /sys/include/pool.h Sun Jun 28 00:00:00 2026 @@ -1,20 +1,20 @@ typedef struct Pool Pool; struct Pool { char* name; - ulong maxsize; + uintptr maxsize; - ulong cursize; - ulong curfree; - ulong curalloc; + uintptr cursize; + uintptr curfree; + uintptr curalloc; - ulong minarena; /* smallest size of new arena */ - ulong quantum; /* allocated blocks should be multiple of */ - ulong minblock; /* smallest newly allocated block */ + uintptr minarena; /* smallest size of new arena */ + uintptr quantum; /* allocated blocks should be multiple of (2^n) */ + uintptr minblock; /* smallest newly allocated block */ void* freeroot; /* actually Free* */ void* arenalist; /* actually Arena* */ - void* (*alloc)(ulong); + void* (*alloc)(uintptr); int (*merge)(void*, void*); void (*move)(void* from, void* to); @@ -31,11 +31,11 @@ struct Pool { void* private; }; -extern void* poolalloc(Pool*, ulong); -extern void* poolallocalign(Pool*, ulong, ulong, long, ulong); +extern void* poolalloc(Pool*, uintptr); +extern void* poolallocalign(Pool*, uintptr, uintptr, vlong, uintptr); extern void poolfree(Pool*, void*); -extern ulong poolmsize(Pool*, void*); -extern void* poolrealloc(Pool*, void*, ulong); +extern uintptr poolmsize(Pool*, void*); +extern void* poolrealloc(Pool*, void*, uintptr); extern void poolcheck(Pool*); extern int poolcompact(Pool*); extern void poolblockcheck(Pool*, void*); --- /n/sources/plan9/sys/src/libc/port/malloc.c Sat Jan 10 10:00:05 2015 +++ /sys/src/libc/port/malloc.c Sun Jun 28 00:00:00 2026 @@ -3,7 +3,7 @@ #include #include -static void* sbrkalloc(ulong); +static void* sbrkalloc(uintptr); static int sbrkmerge(void*, void*); static void plock(Pool*); static void punlock(Pool*); @@ -14,25 +14,27 @@ typedef struct Private Private; struct Private { Lock lk; int pid; - int printfd; /* gets debugging output if set */ +// long alarm; /* saved during plock */ + short printfd; /* gets debugging output if set */ }; Private sbrkmempriv; static Pool sbrkmem = { .name= "sbrkmem", - .maxsize= (3840UL-1)*1024*1024, /* up to ~0xf0000000 */ + /* see allocinit() for 64-bit overrides */ + .maxsize= (3840UL-1)*1024ul*1024ul, /* up to ~0xf0000000 */ + .quantum= 8 * sizeof(void *), .minarena= 4*1024, - .quantum= 32, .alloc= sbrkalloc, .merge= sbrkmerge, .flags= 0, .lock= plock, - .unlock= punlock, + .unlock= punlock, .print= pprint, .panic= ppanic, - .private= &sbrkmempriv, + .private= &sbrkmempriv, }; Pool *mainmem = &sbrkmem; Pool *imagmem = &sbrkmem; @@ -42,15 +44,16 @@ Pool *imagmem = &sbrkmem; * whether two blocks are adjacent and thus mergeable. */ static void* -sbrkalloc(ulong n) +sbrkalloc(uintptr n) { - ulong *x; + uintptr *x; - n += 2*sizeof(ulong); /* two longs for us */ - x = sbrk(n); - if(x == (void*)-1) + n += 2*sizeof(uintptr); /* two ptrs for us */ + /* sbrk takes a ulong, so use brk */ + x = sbrk(0); + if (brk((char *)x + n) < 0) return nil; - x[0] = (n+7)&~7; /* sbrk rounds size up to mult. of 8 */ + x[0] = (n+7)&~7ULL; /* sbrk rounds size up to mult. of 8 */ x[1] = 0xDeadBeef; return x+2; } @@ -58,7 +61,7 @@ sbrkalloc(ulong n) static int sbrkmerge(void *x, void *y) { - ulong *lx, *ly; + uintptr *lx, *ly; lx = x; if(lx[-1] != 0xDeadBeef) @@ -72,12 +75,18 @@ sbrkmerge(void *x, void *y) return 0; } +/* + * a note (e.g., an alarm) arriving between plock and punlock will cause + * a deadlock if the note handler calls malloc, even indirectly. + */ static void plock(Pool *p) { Private *pv; + pv = p->private; lock(&pv->lk); +// pv->alarm = alarm(0); /* defer one source of notes */ if(pv->pid != 0) abort(); pv->pid = _tos->pid; @@ -87,11 +96,13 @@ static void punlock(Pool *p) { Private *pv; + pv = p->private; if(pv->pid != _tos->pid) abort(); pv->pid = 0; unlock(&pv->lk); +// alarm(pv->alarm); } static int @@ -99,6 +110,7 @@ checkenv(void) { int n, fd; char buf[20]; + fd = open("/env/MALLOCFD", OREAD); if(fd < 0) return -1; @@ -134,6 +146,7 @@ pprint(Pool *p, char *fmt, ...) } static char panicbuf[256]; + static void ppanic(Pool *p, char *fmt, ...) { @@ -170,7 +183,7 @@ ppanic(Pool *p, char *fmt, ...) /* - except the code for malloc(), which alternately doesn't clear or does. - */ /* - * Npadlong is the number of 32-bit longs to leave at the beginning of + * Npadptrs is the number of pointers to leave at the beginning of * each allocated buffer for our own bookkeeping. We return to the callers * a pointer that points immediately after our bookkeeping area. Incoming pointers * must be decremented by that much, and outgoing pointers incremented. @@ -178,35 +191,64 @@ ppanic(Pool *p, char *fmt, ...) * and the realloc tag at ReallocOffset. The offsets are from the true beginning * of the block, not the beginning the caller sees. * - * The extra if(Npadlong != 0) in various places is a hint for the compiler to + * The extra if(Npadptrs != 0) in various places is a hint for the compiler to * compile out function calls that would otherwise be no-ops. */ /* non tracing * enum { - Npadlong = 0, - MallocOffset = 0, - ReallocOffset = 0, + Npadptrs = 0, + MallocOffset = 0, + ReallocOffset = 0, }; * */ /* tracing */ enum { - Npadlong = 2, - MallocOffset = 0, - ReallocOffset = 1 + Npadptrs = 2, + MallocOffset = 0, + ReallocOffset = 1 }; +enum { + Npadbytes = Npadptrs * sizeof(void *), +}; + +static int firstalloc = 1; + +static void +allocinit(void) +{ + if (!firstalloc) + return; + firstalloc = 0; + plock(&sbrkmem); + if (sizeof(void *) == sizeof(vlong)) { + sbrkmem.maxsize = 128ll << 40; + /* pool's MINBLOCKSIZE is 64 on 64-bit systems */ + sbrkmem.minblock = 64; + } + punlock(&sbrkmem); + /* + * not sure why this helps, but it prevents poolfreel from + * dying later after large allocations, at least on 64-bit systems. + */ + malloc(8); +} + +#define initialalloc() if (firstalloc) allocinit(); else {} + void* -malloc(ulong size) +malloc(uintptr size) { void *v; - v = poolalloc(mainmem, size+Npadlong*sizeof(ulong)); - if(Npadlong && v != nil) { - v = (ulong*)v+Npadlong; + initialalloc(); + v = poolalloc(mainmem, size + Npadbytes); + if(Npadptrs && v != nil) { + v = (uintptr *)v + Npadptrs; setmalloctag(v, getcallerpc(&size)); setrealloctag(v, 0); } @@ -214,13 +256,14 @@ malloc(ulong size) } void* -mallocz(ulong size, int clr) +mallocz(uintptr size, int clr) { void *v; - v = poolalloc(mainmem, size+Npadlong*sizeof(ulong)); - if(Npadlong && v != nil){ - v = (ulong*)v+Npadlong; + initialalloc(); + v = poolalloc(mainmem, size+Npadbytes); + if(Npadptrs && v != nil){ + v = (uintptr *)v + Npadptrs; setmalloctag(v, getcallerpc(&size)); setrealloctag(v, 0); } @@ -230,13 +273,14 @@ mallocz(ulong size, int clr) } void* -mallocalign(ulong size, ulong align, long offset, ulong span) +mallocalign(uintptr size, uintptr align, vlong offset, uintptr span) { void *v; - v = poolallocalign(mainmem, size+Npadlong*sizeof(ulong), align, offset-Npadlong*sizeof(ulong), span); - if(Npadlong && v != nil){ - v = (ulong*)v+Npadlong; + initialalloc(); + v = poolallocalign(mainmem, size+Npadbytes, align, offset-Npadbytes, span); + if(Npadptrs && v != nil){ + v = (uintptr *)v + Npadptrs; setmalloctag(v, getcallerpc(&size)); setrealloctag(v, 0); } @@ -247,25 +291,26 @@ void free(void *v) { if(v != nil) - poolfree(mainmem, (ulong*)v-Npadlong); + poolfree(mainmem, (uintptr *)v-Npadptrs); } void* -realloc(void *v, ulong size) +realloc(void *v, uintptr size) { void *nv; + initialalloc(); if(size == 0){ free(v); return nil; } if(v) - v = (ulong*)v-Npadlong; - size += Npadlong*sizeof(ulong); + v = (uintptr *)v - Npadptrs; + size += Npadbytes; if(nv = poolrealloc(mainmem, v, size)){ - nv = (ulong*)nv+Npadlong; + nv = (uintptr *)nv + Npadptrs; setrealloctag(nv, getcallerpc(&v)); if(v == nil) setmalloctag(nv, getcallerpc(&v)); @@ -273,59 +318,52 @@ realloc(void *v, ulong size) return nv; } -ulong +uintptr msize(void *v) { - return poolmsize(mainmem, (ulong*)v-Npadlong)-Npadlong*sizeof(ulong); + return poolmsize(mainmem, (uintptr*)v - Npadptrs) - Npadbytes; } void* -calloc(ulong n, ulong szelem) +calloc(uintptr n, uintptr szelem) { void *v; + if(v = mallocz(n*szelem, 1)) setmalloctag(v, getcallerpc(&n)); return v; } void -setmalloctag(void *v, ulong pc) +setmalloctag(void *v, uintptr pc) { - ulong *u; - USED(v, pc); - if(Npadlong <= MallocOffset || v == nil) + if(Npadptrs <= MallocOffset || v == nil) return; - u = v; - u[-Npadlong+MallocOffset] = pc; + ((uintptr *)v)[-Npadptrs+MallocOffset] = pc; } void -setrealloctag(void *v, ulong pc) +setrealloctag(void *v, uintptr pc) { - ulong *u; - USED(v, pc); - if(Npadlong <= ReallocOffset || v == nil) + if(Npadptrs <= ReallocOffset || v == nil) return; - u = v; - u[-Npadlong+ReallocOffset] = pc; + ((uintptr *)v)[-Npadptrs+ReallocOffset] = pc; } -ulong +uintptr getmalloctag(void *v) { - USED(v); - if(Npadlong <= MallocOffset) + if(Npadptrs <= MallocOffset) return ~0; - return ((ulong*)v)[-Npadlong+MallocOffset]; + return ((uintptr *)v)[-Npadptrs+MallocOffset]; } -ulong +uintptr getrealloctag(void *v) { - USED(v); - if(Npadlong <= ReallocOffset) - return ((ulong*)v)[-Npadlong+ReallocOffset]; - return ~0; + if(Npadptrs <= ReallocOffset) + return ~0; + return ((uintptr *)v)[-Npadptrs+ReallocOffset]; } void* @@ -333,6 +371,5 @@ malloctopoolblock(void *v) { if(v == nil) return nil; - - return &((ulong*)v)[-Npadlong]; + return &((uintptr *)v)[-Npadptrs]; } --- /n/sources/plan9/sys/src/libc/port/pool.c Sat Jan 10 10:00:05 2015 +++ /sys/src/libc/port/pool.c Sun Jun 28 00:00:00 2026 @@ -42,6 +42,8 @@ #include #include +#define CTASSERT(cond, name) struct { char name[(cond)? 1: -1]; } + typedef struct Alloc Alloc; typedef struct Arena Arena; typedef struct Bhdr Bhdr; @@ -50,13 +52,19 @@ typedef struct Free Free; struct Bhdr { ulong magic; - ulong size; + uintptr size; }; enum { NOT_MAGIC = 0xdeadfa11, DEAD_MAGIC = 0xdeaddead, + + Ushortsz = 0x10000, }; -#define B2NB(b) ((Bhdr*)((uchar*)(b)+(b)->size)) +/* unsafe macro */ +#define Abovemin(n, bsz, p) \ + ((n) >= (bsz)>>2 && (n) >= MINBLOCKSIZE && (n) >= (p)->minblock) + +#define B2NB(b) ((Bhdr*)((uchar*)(b) + (b)->size)) #define SHORT(x) (((x)[0] << 8) | (x)[1]) #define PSHORT(p, x) \ @@ -71,7 +79,7 @@ struct Btail { uchar magic0; uchar datasize[2]; uchar magic1; - ulong size; /* same as Bhdr->size */ + uintptr size; /* same as Bhdr->size */ }; #define B2T(b) ((Btail*)((uchar*)(b)+(b)->size-sizeof(Btail))) #define B2PT(b) ((Btail*)((uchar*)(b)-sizeof(Btail))) @@ -86,6 +94,7 @@ struct Free { enum { FREE_MAGIC = 0xBA5EBA11, }; +CTASSERT(sizeof(Btail) == sizeof(Bhdr), same_size); /* * the point of the notused fields is to make 8c differentiate @@ -99,13 +108,19 @@ enum { UNALLOC_MAGIC = 0xCAB00D1E+1, }; +/* must be multiple of 8 bytes long */ struct Arena { - Bhdr; + Bhdr; /* 8 or 16 bytes, per sizeof uintptr */ Arena* aup; Arena* down; - ulong asize; - ulong pad; /* to a multiple of 8 bytes */ + uintptr asize; +#ifndef _BITS64 + ulong _pad; +#endif }; + +CTASSERT(sizeof(Arena) % 8 == 0, Arena_multiple_of_8_bytes); + enum { ARENA_MAGIC = 0xC0A1E5CE+1, ARENATAIL_MAGIC = 0xEC5E1A0C+1, @@ -125,8 +140,8 @@ static uchar datamagic[] = { 0xFE, 0xF1, 0xF0, 0xFA }; #define Poison (void*)0xCafeBabe -#define _B2D(a) ((void*)((uchar*)a+sizeof(Bhdr))) -#define _D2B(v) ((Alloc*)((uchar*)v-sizeof(Bhdr))) +#define _B2D(a) ((void*)((uchar*)(a)+sizeof(Bhdr))) +#define _D2B(v) ((Alloc*)((uchar*)(v)-sizeof(Bhdr))) // static void* _B2D(void*); // static void* _D2B(void*); @@ -135,18 +150,18 @@ static Alloc* D2B(Pool*, void*); static Arena* arenamerge(Pool*, Arena*, Arena*); static void blockcheck(Pool*, Bhdr*); static Alloc* blockmerge(Pool*, Bhdr*, Bhdr*); -static Alloc* blocksetdsize(Pool*, Alloc*, ulong); -static Bhdr* blocksetsize(Bhdr*, ulong); -static ulong bsize2asize(Pool*, ulong); -static ulong dsize2bsize(Pool*, ulong); -static ulong getdsize(Alloc*); -static Alloc* trim(Pool*, Alloc*, ulong); +static Alloc* blocksetdsize(Pool*, Alloc*, uintptr); +static Bhdr* blocksetsize(Bhdr*, uintptr); +static uintptr bsize2asize(Pool*, uintptr); +static uintptr dsize2bsize(Pool*, uintptr); +static uintptr getdsize(Alloc*); +static Alloc* trim(Pool*, Alloc*, uintptr); static Free* listadd(Free*, Free*); static void logstack(Pool*); -static Free** ltreewalk(Free**, ulong); -static void memmark(void*, int, ulong); +static Free** ltreewalk(Free**, uintptr); +static void memmark(void*, int, uintptr); static Free* pooladd(Pool*, Alloc*); -static void* poolallocl(Pool*, ulong); +static void* poolallocl(Pool*, uintptr); static void poolcheckl(Pool*); static void poolcheckarena(Pool*, Arena*); static int poolcompactl(Pool*); @@ -154,12 +169,12 @@ static Alloc* pooldel(Pool*, Free*); static void pooldumpl(Pool*); static void pooldumparena(Pool*, Arena*); static void poolfreel(Pool*, void*); -static void poolnewarena(Pool*, ulong); -static void* poolreallocl(Pool*, void*, ulong); +static void poolnewarena(Pool*, uintptr); +static void* poolreallocl(Pool*, void*, uintptr); static Free* treedelete(Free*, Free*); static Free* treeinsert(Free*, Free*); -static Free* treelookup(Free*, ulong); -static Free* treelookupgt(Free*, ulong); +static Free* treelookup(Free*, uintptr); +static Free* treelookupgt(Free*, uintptr); /* * Debugging @@ -211,7 +226,7 @@ checklist(Free *t) } static void -checktree(Free *t, int a, int b) +checktree(Free *t, uintptr a, uintptr b) { assert(t->magic==FREE_MAGIC); assert(a < t->size && t->size < b); @@ -227,7 +242,7 @@ checktree(Free *t, int a, int b) /* ltreewalk: return address of pointer to node of size == size */ static Free** -ltreewalk(Free **t, ulong size) +ltreewalk(Free **t, uintptr size) { assert(t != nil /* ltreewalk */); @@ -248,7 +263,7 @@ ltreewalk(Free **t, ulong size) /* treelookup: find node in tree with size == size */ static Free* -treelookup(Free *t, ulong size) +treelookup(Free *t, uintptr size) { return *ltreewalk(&t, size); } @@ -306,7 +321,7 @@ treedelete(Free *tree, Free *node) /* treelookupgt: find smallest node in tree with size >= size */ static Free* -treelookupgt(Free *t, ulong size) +treelookupgt(Free *t, uintptr size) { Free *lastgood; /* last node we saw that was big enough */ @@ -428,8 +443,8 @@ pooldel(Pool *p, Free *node) * Block maintenance */ /* block allocation */ -static ulong -dsize2bsize(Pool *p, ulong sz) +static uintptr +dsize2bsize(Pool *p, uintptr sz) { sz += sizeof(Bhdr)+sizeof(Btail); if(sz < p->minblock) @@ -440,8 +455,8 @@ dsize2bsize(Pool *p, ulong sz) return sz; } -static ulong -bsize2asize(Pool *p, ulong sz) +static uintptr +bsize2asize(Pool *p, uintptr sz) { sz += sizeof(Arena)+sizeof(Btail); if(sz < p->minarena) @@ -466,8 +481,7 @@ blockmerge(Pool *pool, Bhdr *a, Bhdr *b) t = B2T(a); t->size = (ulong)Poison; - t->magic0 = NOT_MAGIC; - t->magic1 = NOT_MAGIC; + t->magic0 = t->magic1 = NOT_MAGIC; PSHORT(t->datasize, NOT_MAGIC); a->size += b->size; @@ -484,11 +498,14 @@ blockmerge(Pool *pool, Bhdr *a, Bhdr *b) /* blocksetsize: set the total size of a block, fixing tail pointers */ static Bhdr* -blocksetsize(Bhdr *b, ulong bsize) +blocksetsize(Bhdr *b, uintptr bsize) { Btail *t; + uvlong vbsize; assert(b->magic != FREE_MAGIC /* blocksetsize */); + vbsize = bsize; + assert(vbsize < (1ll << 48)); /* amd64 sanity hack TODO */ b->size = bsize; t = B2T(b); @@ -499,7 +516,7 @@ blocksetsize(Bhdr *b, ulong bsize) } /* getdsize: return the requested data size for an allocated block */ -static ulong +static uintptr getdsize(Alloc *b) { Btail *t; @@ -509,13 +526,14 @@ getdsize(Alloc *b) /* blocksetdsize: set the user data size of a block */ static Alloc* -blocksetdsize(Pool *p, Alloc *b, ulong dsize) +blocksetdsize(Pool *p, Alloc *b, uintptr dsize) { Btail *t; uchar *q, *eq; assert(b->size >= dsize2bsize(p, dsize)); - assert(b->size - dsize < 0x10000); + /* must fit in ushort for t->datasize */ + assert(b->size - dsize < Ushortsz); t = B2T(b); PSHORT(t->datasize, b->size - dsize); @@ -525,22 +543,22 @@ blocksetdsize(Pool *p, Alloc *b, ulong dsize) if(eq > q+4) eq = q+4; for(; qsize - bsize; - if(b->size - dsize >= 0x10000 || - (extra >= bsize>>2 && extra >= MINBLOCKSIZE && extra >= p->minblock)) { + /* b->size - dsize must fit in ushort */ + if(b->size - dsize >= Ushortsz || Abovemin(extra, bsize, p)) { blocksetsize(b, bsize); frag = (Alloc*) B2NB(b); @@ -559,12 +577,12 @@ trim(Pool *p, Alloc *b, ulong dsize) } static Alloc* -freefromfront(Pool *p, Alloc *b, ulong skip) +freefromfront(Pool *p, Alloc *b, uintptr skip) { Alloc *bb; - skip = skip&~(p->quantum-1); - if(skip >= 0x1000 || (skip >= b->size>>2 && skip >= MINBLOCKSIZE && skip >= p->minblock)){ + skip &= ~(p->quantum-1); + if(skip >= Ushortsz || Abovemin(skip, b->size, p)) { bb = (Alloc*)((uchar*)b+skip); blocksetsize(bb, b->size-skip); bb->magic = UNALLOC_MAGIC; @@ -582,7 +600,7 @@ freefromfront(Pool *p, Alloc *b, ulong skip) /* arenasetsize: set arena size, updating tail */ static void -arenasetsize(Arena *a, ulong asize) +arenasetsize(Arena *a, uintptr asize) { Bhdr *atail; @@ -594,22 +612,25 @@ arenasetsize(Arena *a, ulong asize) /* poolnewarena: allocate new arena */ static void -poolnewarena(Pool *p, ulong asize) +poolnewarena(Pool *p, uintptr asize) { - Arena *a; - Arena *ap, *lastap; + Arena *a, *ap, *lastap; Alloc *b; - LOG(p, "newarena %lud\n", asize); + LOG(p, "newarena %llud\n", (uvlong)asize); if(p->cursize+asize > p->maxsize) { if(poolcompactl(p) == 0){ - LOG(p, "pool too big: %lud+%lud > %lud\n", - p->cursize, asize, p->maxsize); + LOG(p, "pool too big: %llud+%llud > %llud\n", + (uvlong)p->cursize, (uvlong)asize, + (uvlong)p->maxsize); werrstr("memory pool too large"); } return; } + /* sbrk takes a ulong; limit here as a hack */ + if (0 && asize >= (1ull<<32)) + asize = (ulong)~0ul; if((a = p->alloc(asize)) == nil) { /* assume errstr set by p->alloc */ return; @@ -654,11 +675,12 @@ poolnewarena(Pool *p, ulong asize) /* blockresize: grow a block to encompass space past its end, possibly by */ /* trimming it into two different blocks. */ static void -blockgrow(Pool *p, Bhdr *b, ulong nsize) +blockgrow(Pool *p, Bhdr *b, uintptr nsize) { if(b->magic == FREE_MAGIC) { Alloc *a; Bhdr *bnxt; + a = pooldel(p, (Free*)b); blockcheck(p, a); blocksetsize(a, nsize); @@ -670,7 +692,7 @@ blockgrow(Pool *p, Bhdr *b, ulong nsize) pooladd(p, a); } else { Alloc *a; - ulong dsize; + uintptr dsize; a = (Alloc*)b; dsize = getdsize(a); @@ -720,7 +742,7 @@ static void dumpblock(Pool *p, Bhdr *b) { ulong *dp; - ulong dsize; + uintptr dsize; uchar *cp; dp = (ulong*)b; @@ -767,9 +789,8 @@ blockcheck(Pool *p, Bhdr *b) { Alloc *a; Btail *t; - int i, n; + uintptr i, n, dsize; uchar *q, *bq, *eq; - ulong dsize; switch(b->magic) { default: @@ -789,9 +810,8 @@ blockcheck(Pool *p, Bhdr *b) if(T2HDR(t) != b) panicblock(p, b, "corrupt tail ptr"); n = getdsize((Alloc*)b); - q = _B2D(b); - q += 8; - for(i=8; imagic0 != TAIL_MAGIC0){ - /* if someone wrote exactly one byte over and it was a NUL, we sometimes only complain. */ + /* + * if someone wrote exactly one byte over and it was a + * NUL, we sometimes only complain. + */ if((p->flags & POOL_TOLERANCE) && bq == eq && t->magic0 == 0) printblock(p, b, "mem user overflow (magic0)"); else @@ -830,7 +853,7 @@ blockcheck(Pool *p, Bhdr *b) if(eq > bq+4) eq = bq+4; for(q=bq; qflags & POOL_TOLERANCE)){ printblock(p, b, "mem user overflow"); continue; @@ -958,8 +981,8 @@ D2B(Pool *p, void *v) Alloc *a; ulong *u; - if((uintptr)v&(sizeof(ulong)-1)) - v = (char*)v - ((uintptr)v&(sizeof(ulong)-1)); + if((uintptr)v & (sizeof(ulong)-1)) + v = (char*)v - ((uintptr)v & (sizeof(ulong)-1)); u = v; while(u[-1] == ALIGN_MAGIC) u--; @@ -971,13 +994,15 @@ D2B(Pool *p, void *v) /* poolallocl: attempt to allocate block to hold dsize user bytes; assumes lock held */ static void* -poolallocl(Pool *p, ulong dsize) +poolallocl(Pool *p, uintptr dsize) { - ulong bsize; + vlong ssize; + uintptr bsize; Free *fb; Alloc *ab; - if(dsize >= 0x80000000UL){ /* for sanity, overflow */ + ssize = dsize; + if (ssize < 0){ /* for sanity, overflow */ werrstr("invalid allocation size"); return nil; } @@ -1003,14 +1028,12 @@ poolallocl(Pool *p, ulong dsize) /* poolreallocl: attempt to grow v to ndsize bytes; assumes lock held */ static void* -poolreallocl(Pool *p, void *v, ulong ndsize) +poolreallocl(Pool *p, void *v, uintptr ndsize) { Alloc *a; Bhdr *left, *right, *newb; Btail *t; - ulong nbsize; - ulong odsize; - ulong obsize; + uintptr nbsize, odsize, obsize; void *nv; if(v == nil) /* for ANSI */ @@ -1075,18 +1098,19 @@ poolreallocl(Pool *p, void *v, ulong ndsize) /* enough cleverness */ memmove(nv, v, odsize); - antagonism { - memset((char*)nv+odsize, 0xDE, ndsize-odsize); + antagonism { + if (ndsize > odsize) + memset((char*)nv+odsize, 0xDE, ndsize-odsize); } poolfreel(p, v); return nv; } static void* -alignptr(void *v, ulong align, long offset) +alignptr(void *v, uintptr align, vlong offset) // TODO need intptr { char *c; - ulong off; + uintptr off; c = v; if(align){ @@ -1102,13 +1126,13 @@ alignptr(void *v, ulong align, long offset) /* poolallocalignl: allocate as described below; assumes pool locked */ static void* -poolallocalignl(Pool *p, ulong dsize, ulong align, long offset, ulong span) +poolallocalignl(Pool *p, uintptr dsize, uintptr align, vlong offset, uintptr span) // TODO need intptr { - ulong asize; - void *v; + int skip; + uintptr asize; char *c; ulong *u; - int skip; + void *v; Alloc *b; /* @@ -1152,7 +1176,8 @@ poolallocalignl(Pool *p, ulong dsize, ulong align, long offset, ulong span) c = alignptr(c, align, offset); if((uintptr)c/span != (uintptr)(c+dsize-1)/span){ poolfreel(p, v); - werrstr("cannot satisfy dsize %lud span %lud with align %lud+%ld", dsize, span, align, offset); + werrstr("cannot satisfy dsize %llud span %llud with align %llud+%lld", + (uvlong)dsize, (uvlong)span, (uvlong)align, offset); return nil; } } @@ -1193,12 +1218,12 @@ poolfreel(Pool *p, void *v) blockcheck(p, ab); if(p->flags&POOL_NOREUSE){ - int n; + vlong n; ab->magic = DEAD_MAGIC; - n = getdsize(ab)-8; + n = getdsize(ab) - sizeof(Bhdr); if(n > 0) - memset((uchar*)v+8, 0xDA, n); + memset((uchar*)v + sizeof(Bhdr), 0xDA, n); return; } @@ -1216,7 +1241,7 @@ poolfreel(Pool *p, void *v) } void* -poolalloc(Pool *p, ulong n) +poolalloc(Pool *p, uintptr n) { void *v; @@ -1241,7 +1266,7 @@ poolalloc(Pool *p, ulong n) } void* -poolallocalign(Pool *p, ulong n, ulong align, long offset, ulong span) +poolallocalign(Pool *p, uintptr n, uintptr align, vlong offset, uintptr span) { void *v; @@ -1290,7 +1315,7 @@ poolcompact(Pool *p) } void* -poolrealloc(Pool *p, void *v, ulong n) +poolrealloc(Pool *p, void *v, uintptr n) { void *nv; @@ -1339,11 +1364,11 @@ poolfree(Pool *p, void *v) /* * Return the real size of a block, and let the user use it. */ -ulong +uintptr poolmsize(Pool *p, void *v) { Alloc *b; - ulong dsize; + uintptr dsize; p->lock(p); paranoia { @@ -1379,15 +1404,19 @@ poolmsize(Pool *p, void *v) static void poolcheckarena(Pool *p, Arena *a) { - Bhdr *b; - Bhdr *atail; + Bhdr *b, *atail; atail = A2TB(a); - for(b=a; b->magic != ARENATAIL_MAGIC && b atail) + p->panic(p, "arena beyond tail; pool %#llux arena %#llux magic %#llux atail %#llux", + (uvlong)p, (uvlong)a, (uvlong)a->magic, (uvlong)atail); + for(b = a; b->magic != ARENATAIL_MAGIC && bpanic(p, "found wrong tail"); + p->panic(p, "found wrong tail; pool %#llux arena %#llux magic %#llux b %#llux magic %#llux atail %#llux", + (uvlong)p, (uvlong)a, (uvlong)a->magic, (uvlong)b, + (uvlong)b->magic, (uvlong)atail); } static void @@ -1398,7 +1427,8 @@ poolcheckl(Pool *p) for(a=p->arenalist; a; a=a->down) poolcheckarena(p, a); if(p->freeroot) - checktree(p->freeroot, 0, 1<<30); + checktree(p->freeroot, 0, (sizeof(void *) == sizeof(vlong)? + 1ull<<46: 1<<30)); } void @@ -1444,7 +1474,7 @@ pooldumparena(Pool *p, Arena *a) Bhdr *b; for(b=a; b->magic != ARENATAIL_MAGIC; b=B2NB(b)) - p->print(p, "(%p %.8lux %lud)", b, b->magic, b->size); + p->print(p, "(%p %.8lux %llud)", b, b->magic, (uvlong)b->size); p->print(p, "\n"); } @@ -1453,16 +1483,17 @@ pooldumparena(Pool *p, Arena *a) * (via the signature) and we know where the marking started. */ static void -memmark(void *v, int sig, ulong size) +memmark(void *v, int sig, uintptr size) { uchar *p, *ep; ulong *lp, *elp; + lp = v; elp = lp+size/4; while(lp < elp) - *lp++ = (sig<<24) ^ ((uintptr)lp-(uintptr)v); + *lp++ = (sig<<24) ^ ((uintptr)lp - (uintptr)v); p = (uchar*)lp; ep = (uchar*)v+size; - while(p .PP .B -void* poolalloc(Pool* pool, ulong size) +void* poolalloc(Pool* pool, uintptr size) .PP .B -void* poolallocalign(Pool *pool, ulong size, +void* poolallocalign(Pool *pool, uintptr size, .br .B - ulong align, long offset, ulong span) + uintptr align, vlong offset, uintptr span) .PP .B void poolfree(Pool* pool, void* ptr) .PP .B -ulong poolmsize(Pool* pool, void* ptr) +uintptr poolmsize(Pool* pool, void* ptr) .PP .B -void* poolrealloc(Pool* pool, void* ptr, ulong size) +void* poolrealloc(Pool* pool, void* ptr, uintptr size) .PP .B void poolcompact(Pool* pool) @@ -129,21 +129,21 @@ structure itself provides much of the setup interface. .IP .EX -.ta \w'\fL 'u +\w'\fLulong 'u +\w'\fLlastcompact; 'u +.ta \w'\fL 'u +\w'\fLuintptr 'u +\w'\fLlastcompact; 'u typedef struct Pool Pool; struct Pool { char* name; - ulong maxsize; /* of entire Pool */ - ulong cursize; /* of Pool */ - ulong curfree; /* total free bytes in Pool */ - ulong curalloc; /* total allocated bytes in Pool */ - ulong minarena; /* smallest size of new arena */ - ulong quantum; /* allocated blocks should be multiple of */ - ulong minblock; /* smallest newly allocated block */ + uintptr maxsize; /* of entire Pool */ + uintptr cursize; /* of Pool */ + uintptr curfree; /* total free bytes in Pool */ + uintptr curalloc; /* total allocated bytes in Pool */ + uintptr minarena; /* smallest size of new arena */ + uintptr quantum; /* allocated blocks should be multiple of */ + uintptr minblock; /* smallest newly allocated block */ int flags; int nfree; /* number of calls to free */ int lastcompact; /* nfree at time of last poolcompact */ - void* (*alloc)(ulong); + void* (*alloc)(uintptr); int (*merge)(void*, void*); void (*move)(void* from, void* to); void (*lock)(Pool*);