libc: Add poolreset() function

This is intended for the secrmem pool in the kernel,
but could also be used for temporary pools to
recover the memory used by the arenas.
This commit is contained in:
cinap_lenrek 2023-04-08 20:24:44 +00:00
parent 26e42d1159
commit bd43bd6f1a
5 changed files with 64 additions and 2 deletions

View file

@ -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*);

View file

@ -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

View file

@ -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

View file

@ -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
*/

View file

@ -29,6 +29,8 @@ UPDATE=\
</sys/src/cmd/mksyslib
alloc.$O draw.$O: /sys/include/pool.h
$O.drawtest: drawtest.$O $LIB
$LD -o $target $prereq