code: plan9front

Download patch

ref: bd43bd6f1ae1b1ec7ee6873d9fd6766b049802e9
parent: 26e42d115979009c9fe144e1c28f740485537674
author: cinap_lenrek <cinap_lenrek@felloff.net>
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