diff --git a/sys/include/pool.h b/sys/include/pool.h index 5f7fada45..55ca6f59d 100644 --- a/sys/include/pool.h +++ b/sys/include/pool.h @@ -17,6 +17,7 @@ struct Pool { void* (*alloc)(ulong); int (*merge)(void*, void*); void (*move)(void* from, void* to); + void (*free)(void*, ulong); int flags; int nfree; @@ -36,6 +37,7 @@ extern void* poolallocalign(Pool*, ulong, ulong, long, ulong); extern void poolfree(Pool*, void*); extern ulong poolmsize(Pool*, void*); extern int poolisoverlap(Pool*, void*, ulong); +extern void poolreset(Pool*); extern void* poolrealloc(Pool*, void*, ulong); extern void poolcheck(Pool*); extern int poolcompact(Pool*); diff --git a/sys/man/2/pool b/sys/man/2/pool index 1360484e9..20636fad5 100644 --- a/sys/man/2/pool +++ b/sys/man/2/pool @@ -28,6 +28,9 @@ ulong poolmsize(Pool* pool, void* ptr) int poolisoverlap(Pool* pool, void* ptr, ulong len) .PP .B +void poolreset(Pool* pool) +.PP +.B void* poolrealloc(Pool* pool, void* ptr, ulong size) .PP .B @@ -119,6 +122,18 @@ overlaps the arenas of the specified .BR pool , returning non-zero when there is overlap or zero if none. .PP +.I Poolreset +clears the pool counters and frees all arenas. +The arenas are filled with a pattern before +freeing them when the +.B POOL_ANTAGONISM +flag is set. +When the +.B free +function of the pool is non-nil, +it is called for each arena, +passing its pointer and size. +.PP The .I poolblockcheck and @@ -156,6 +171,7 @@ struct Pool { void* (*alloc)(ulong); int (*merge)(void*, void*); void (*move)(void* from, void* to); + void (*free)(void*, ulong); void (*lock)(Pool*); void (*unlock)(Pool*); void (*print)(Pool*, char*, ...); @@ -279,12 +295,15 @@ Specifically, each 32-bit word of the memory is marked with a pointer value excl with a constant. The pointer value is the pointer to the beginning of the allocated block and the constant varies in order to distinguish different markings. -Freed blocks use the constant +Freed blocks use the constant .BR 0xF7000000 , newly allocated blocks .BR 0xF9000000 , and newly created unallocated blocks -.BR 0xF1000000 . +.BR 0xF1000000 , +freed arenas after +.I poolreset +.BR 0xFF000000 . For example, if .B POOL_ANTAGONISM is set and diff --git a/sys/src/libc/port/mkfile b/sys/src/libc/port/mkfile index 557f1d7fa..683e6c583 100644 --- a/sys/src/libc/port/mkfile +++ b/sys/src/libc/port/mkfile @@ -131,6 +131,8 @@ UPDATE=mkfile\ profile.$O: /sys/include/tos.h +malloc.$O pool.$O: /sys/include/pool.h + runenorm.$O: runenormdata runenorm.c runetotype.$O: runetotypedata runetotype.c runeistype.$O: runeistypedata runeistype.c diff --git a/sys/src/libc/port/pool.c b/sys/src/libc/port/pool.c index 546d5776a..34254f7f5 100644 --- a/sys/src/libc/port/pool.c +++ b/sys/src/libc/port/pool.c @@ -1345,6 +1345,43 @@ poolisoverlap(Pool *p, void *v, ulong n) return a != nil; } +void +poolreset(Pool *p) +{ + Arena *a; + + if(p == nil) + return; + + p->lock(p); + paranoia { + poolcheckl(p); + } + verbosity { + pooldumpl(p); + } + p->cursize = 0; + p->curfree = 0; + p->curalloc = 0; + p->lastcompact = p->nfree = 0; + p->freeroot = nil; + a = p->arenalist; + p->arenalist = nil; + LOG(p, "poolreset %p\n", p); + p->unlock(p); + + while(a != nil){ + Arena *next = a->down; + ulong asize = a->asize; + antagonism { + memmark(a, 0xFF, asize); + } + if(p->free) + p->free(a, asize); + a = next; + } +} + /* * Debugging */ diff --git a/sys/src/libmemdraw/mkfile b/sys/src/libmemdraw/mkfile index 584396a46..cf882b4b6 100644 --- a/sys/src/libmemdraw/mkfile +++ b/sys/src/libmemdraw/mkfile @@ -29,6 +29,8 @@ UPDATE=\