ref: bd43bd6f1ae1b1ec7ee6873d9fd6766b049802e9
parent: 26e42d115979009c9fe144e1c28f740485537674
author: cinap_lenrek <[email protected]>
date: Sat Apr 8 16:24:44 EDT 2023
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.
--- a/sys/include/pool.h
+++ b/sys/include/pool.h
@@ -17,6 +17,7 @@
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 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*);
--- a/sys/man/2/pool
+++ b/sys/man/2/pool
@@ -28,6 +28,9 @@
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 @@
.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 @@
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 @@
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
--- a/sys/src/libc/port/mkfile
+++ b/sys/src/libc/port/mkfile
@@ -131,6 +131,8 @@
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
--- a/sys/src/libc/port/pool.c
+++ b/sys/src/libc/port/pool.c
@@ -1345,6 +1345,43 @@
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
*/
--- a/sys/src/libmemdraw/mkfile
+++ b/sys/src/libmemdraw/mkfile
@@ -29,6 +29,8 @@
</sys/src/cmd/mksyslib
+alloc.$O draw.$O: /sys/include/pool.h
+
$O.drawtest: drawtest.$O $LIB
$LD -o $target $prereq