summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2023-04-08 20:24:44 +0000
committercinap_lenrek <cinap_lenrek@felloff.net>2023-04-08 20:24:44 +0000
commitbd43bd6f1ae1b1ec7ee6873d9fd6766b049802e9 (patch)
tree6b846a12ebf42feaf394de84ab663d6c3314d984 /sys
parent26e42d115979009c9fe144e1c28f740485537674 (diff)
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.
Diffstat (limited to 'sys')
-rw-r--r--sys/include/pool.h2
-rw-r--r--sys/man/2/pool23
-rw-r--r--sys/src/libc/port/mkfile2
-rw-r--r--sys/src/libc/port/pool.c37
-rw-r--r--sys/src/libmemdraw/mkfile2
5 files changed, 64 insertions, 2 deletions
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=\
</sys/src/cmd/mksyslib
+alloc.$O draw.$O: /sys/include/pool.h
+
$O.drawtest: drawtest.$O $LIB
$LD -o $target $prereq