From c5775f49c4b3ff27916c9425a0bb614df4bde3e4 Mon Sep 17 00:00:00 2001 Message-Id: From: Mark Wooding Date: Sun, 12 Oct 2003 14:44:46 +0000 Subject: [PATCH] Various fixes. Organization: Straylight/Edgeware From: mdw --- Makefile.am | 22 +++++++---- man/crc32.3 | 1 + man/pool.3 | 19 ++++++++-- man/sub.3 | 103 ++++++++++++++++++++++++++++++++++------------------ pool.c | 56 ++++++++++++++++------------ sub.c | 6 ++- sub.h | 14 +++++-- 7 files changed, 146 insertions(+), 75 deletions(-) diff --git a/Makefile.am b/Makefile.am index 81b9515..081f74d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ ## -*-Makefile-*- ## -## $Id: Makefile.am,v 1.36 2003/05/18 15:17:04 mdw Exp $ +## $Id: Makefile.am,v 1.37 2003/10/12 14:44:46 mdw Exp $ ## ## Building the distribution ## @@ -29,6 +29,9 @@ ##----- Revision history ---------------------------------------------------- ## ## $Log: Makefile.am,v $ +## Revision 1.37 2003/10/12 14:44:46 mdw +## Various fixes. +## ## Revision 1.36 2003/05/18 15:17:04 mdw ## Version bump. ## @@ -133,7 +136,8 @@ pkglibexecdir = $(libexecdir)/$(PACKAGE) pkglibexec_PROGRAMS = bres pkginclude_HEADERS = \ - alloc.h arena.h bits.h exc.h quis.h report.h sub.h trace.h track.h \ + align.h alloc.h arena.h bits.h exc.h quis.h report.h sub.h \ + trace.h track.h unihash.h \ pool.h \ atom.h assoc.h darray.h dstr.h dspool.h hash.h sym.h crc32.h \ env.h fdflags.h fwatch.h lock.h \ @@ -149,7 +153,7 @@ libmLib_la_LDFLAGS = -version-info 2:1:0 libmLib_la_SOURCES = \ alloc.c arena.c exc.c quis.c pquis.c report.c sub.c trace.c \ - traceopt.c track.c \ + traceopt.c track.c unihash.c \ pool.c pool-file.c pool-sub.c \ atom.c assoc.c darray.c dstr.c dputf.c dspool.c hash.c sym.c \ crc32.c crc32-tab.c \ @@ -178,9 +182,11 @@ da_t_SOURCES = da-test.c da_t_LDADD = libmLib.la da_t_LDFLAGS = -static da.in: $(srcdir)/da-gtest - perl $(srcdir)/da-gtest 10000 >da.in + perl $(srcdir)/da-gtest 10000 >da.in.new + mv da.in.new da.in da.ref: da.in $(srcdir)/da-ref - perl $(srcdir)/da-ref da.ref + perl $(srcdir)/da-ref da.ref.new + mv da.ref.new da.ref da.test: da.t da.in da.ref ./da.t da.out cmp da.out da.ref @@ -190,9 +196,11 @@ sym_t_SOURCES = sym-test.c sym_t_LDADD = libmLib.la sym_t_LDFLAGS = -static sym.in: $(srcdir)/sym-gtest - perl $(srcdir)/sym-gtest 10000 >sym.in + perl $(srcdir)/sym-gtest 10000 >sym.in.new + mv sym.in.new sym.in sym.ref: sym.in $(srcdir)/sym-ref - perl $(srcdir)/sym-ref sym.ref + perl $(srcdir)/sym-ref sym.ref.new + mv sym.ref.new sym.ref sym.test: sym.t sym.in sym.ref ./sym.t sym.out cmp sym.out sym.ref diff --git a/man/crc32.3 b/man/crc32.3 index c9e34ba..dda3ad0 100644 --- a/man/crc32.3 +++ b/man/crc32.3 @@ -53,6 +53,7 @@ remainder after division by a degree-32 polynomial in GF(2)[x]. .SH "RETURN VALUE" The return value is the 32-bit CRC of the input block. .SH "SEE ALSO" +.BR unihash (3), .BR mLib (3). .SH AUTHOR Mark Wooding, diff --git a/man/pool.3 b/man/pool.3 index 1e806bf..4c3dd5f 100644 --- a/man/pool.3 +++ b/man/pool.3 @@ -16,6 +16,7 @@ pool \- resource pool management .\" @pool_alloc .\" @pool_strdup +.\" @pool_init .\" @pool_create .\" @pool_destroy .\" @pool_sub @@ -28,6 +29,7 @@ pool \- resource pool management .nf .B "#include " +.BI "void pool_init(pool *" p ", arena *" a ); .BI "pool *pool_create(arena *" a ); .BI "pool *pool_sub(pool *" p ); .BI "void pool_destroy(pool *" p ); @@ -76,6 +78,11 @@ of avoiding memory leaks. A new root pool is created using .BR pool_create , passing it an arena from which it can allocate large memory blocks. +Alternatively, you can allocate a +.B pool +structure from somewhere and initialize it by passing its address and an +arena to +.BR pool_init . .PP A subpool is created by calling .BR pool_sub , @@ -83,10 +90,14 @@ naming the parent pool. .PP Pools are destroyed by passing them to .BR pool_destroy . -Root pools are completely destroyed, since the memory containing the -pool structure is allocated from the pool itself. Subpools, on the -other hand, are allocated from a parent pool, and may be reused after -being `destroyed'. +Pools created by +.B pool_create +are completely destroyed, since the memory containing the pool structure +is allocated from the pool itself. Subpools and pools allocated by the +caller and initialized by +.BR pool_init , +on the other hand, are +allocated from a parent pool, and may be reused after being `destroyed'. .SS "Memory allocation" Memory is allocated from a pool by calling .BR pool_alloc , diff --git a/man/sub.3 b/man/sub.3 index e03fb1c..ef61110 100644 --- a/man/sub.3 +++ b/man/sub.3 @@ -14,10 +14,16 @@ .TH sub 3 "8 May 1999" "Straylight/Edgeware" "mLib utilities library" .SH NAME sub \- efficient allocation and freeing of small blocks +.\" @subarena_create +.\" @subarena_destroy +.\" @subarena_alloc +.\" @subarena_free .\" @sub_alloc .\" @sub_free .\" @sub_init .\" +.\" @A_CREATE +.\" @A_DESTROY .\" @CREATE .\" @DESTROY .\" @@ -25,85 +31,110 @@ sub \- efficient allocation and freeing of small blocks .nf .B "#include " +.BI "void subarena_create(subarena *" s ", arena *" a ); +.BI "void subarena_destroy(subarena *" s ); +.BI "void subarena_alloc(subarena *" s ", size_t " sz ); +.BI "void subarena_free(subarena *" s ", void *" p ", size_t " sz ); + .B "void sub_init(void);" .BI "void *sub_alloc(size_t " sz ); .BI "void sub_free(void *" p ", size_t " sz ); +.BI "void *A_CREATE(subarena *" s ", " type ); +.BI "void A_DESTROY(subarena *" s ", " type " *" p ); .BI "void *CREATE(" type ); .BI "void DESTROY(" type " *" p ); .fi .SH DESCRIPTION The -.B sub +.B subarena collection of functions and macros implement an efficient allocator for -small blocks of known sizes. Free blocks of the same size are linked -together in list, making freeing and allocation fast. The `free' -operation requires the block size as an argument, so there's no data -overhead for an allocated block. The system takes advantage of this by -allocating big chunks from the underlying system (actually via -.BR xmalloc (3), -q.v.) and splitting the chunks into smaller blocks of the right size, so -the space and time overhead from the underlying allocator is divided -over many blocks. +small blocks of known sizes, constructed from a general allocator +implemented by an +.BR arena (3). +Free blocks of the same size are linked together in list, making freeing +and allocation fast. The `free' operation requires the block size as an +argument, so there's no data overhead for an allocated block. The +system takes advantage of this by allocating big chunks from the +underlying arena and splitting the chunks into smaller blocks of the +right size, so the space and time overhead from the underlying allocator +is divided over many blocks. .PP Calling -.B sub_alloc +.B subarena_alloc allocates a block of .I sz -bytes. If there isn't enough memory to allocate the block, the +bytes from the subarena +.IR s . +If there isn't enough memory to allocate the block, the exception .B EXC_NOMEM is raised. .PP The -.B sub_free +.B subarena_free function frees a block allocated by -.BR sub_alloc . -You must know the size of the block in advance. Note that -.B sub_free +.B subarena_alloc +from the same subarena. You must know the size of the block in advance. +Note that +.B subarena_free never gives memory back to the underlying allocator. Free sub-blocks are just made available to later calls of -.BR sub_alloc . +.BR subarena_alloc . .PP -Don't try to pass blocks allocated by -.B sub_alloc -to -.BR free (3); -similarly, don't try to pass blocks allocated by -.BR xmalloc (3) -or -.BR malloc (3) -to -.BR sub_free . +Don't try to free blocks allocated by +.B subarena_alloc +to the underlying arena's +.I free +function, or to try freeing blocks obtained directly from the arena's +.I alloc +function using +.BR subarena_free . If you do, you'll get what you deserve. .PP The pair of macros -.B CREATE +.B A_CREATE and -.B DESTROY +.B A_DESTROY are intended to provide a slightly more natural interface to allocation. The call .VS -mystruct *p = sub_alloc(sizeof(mystruct)); +mystruct *p = subarena_alloc(s, sizeof(mystruct)); .VE can be replaced by .VS -mystruct p = CREATE(mystruct); +mystruct p = A_CREATE(s, mystruct); .VE Similarly, the block can be freed by saying .VS -DESTROY(p) +A_DESTROY(s, p) .VE rather than the more cumbersome .VS -sub_free(p, sizeof(*p)); +subarena_free(s, p, sizeof(*p)); .VE +There is a standard subarena +.B sub_global +which uses +.B arena_global +as its underlying allocator (obtained the first time the subarena is +used). The functions +.B sub_alloc +and +.B sub_free +and the macros +.B CREATE +and +.B DESTROY +use this subarena. +.PP The function .B sub_init -must be called before any of the other -.B sub -functions or macros. +ought to be called before any of the other functions as a matter of good +taste, but actually the system will initialize itself the first time +it's used. .SH "SEE ALSO" +.BR arena (3), .BR exc (3), .BR alloc (3), .BR mLib (3). diff --git a/pool.c b/pool.c index 0c4e3ed..1611862 100644 --- a/pool.c +++ b/pool.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: pool.c,v 1.1 2000/07/16 12:28:48 mdw Exp $ + * $Id: pool.c,v 1.2 2003/10/12 14:44:46 mdw Exp $ * * Resource pool handling * @@ -30,6 +30,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: pool.c,v $ + * Revision 1.2 2003/10/12 14:44:46 mdw + * Various fixes. + * * Revision 1.1 2000/07/16 12:28:48 mdw * Support for resource pools, based on the Apache model. * @@ -37,6 +40,7 @@ /*----- Header files ------------------------------------------------------*/ +#include "align.h" #include "alloc.h" #include "arena.h" #include "pool.h" @@ -61,24 +65,13 @@ static void *doalloc(arena *a, pool_chunk **cc, size_t sz) void *p; size_t csz, ssz; - /* --- Round up the requested size --- * - * - * This assumes too much about how various objects are aligned. It could - * do with improvement some time. This is, I believe, the only - * nonportability in the code, and it should work on `sane' architectures - * anyway. - */ - -#define ROUNDUP(sz) ((sz + 15) % 16) - - sz = ROUNDUP(sz); - /* --- See if there's enough space --- * * * The chunks are sorted by available space, so if there's not enough space * in the first chunk there isn't enough space anywhere. */ + ALIGN(sz); c = *cc; if (c && c->left >= sz) { p = c->p; @@ -93,9 +86,10 @@ static void *doalloc(arena *a, pool_chunk **cc, size_t sz) */ else { - ssz = ROUNDUP(sizeof(pool_chunk)); - csz = (ssz + sz + POOL_CHUNKSZ - 1) % POOL_CHUNKSZ; - p = x_alloc(a, csz); + ssz = sizeof(pool_chunk); + ALIGN(ssz); + csz = (ssz + sz + POOL_CHUNKSZ - 1); csz -= csz % POOL_CHUNKSZ; + c = x_alloc(a, csz); p = (char *)c + ssz; c->p = (char *)p + sz; c->left = csz - ssz - sz; @@ -111,8 +105,6 @@ static void *doalloc(arena *a, pool_chunk **cc, size_t sz) /* --- Done --- */ return (p); - -#undef ROUNDUP } /* --- @pool_alloc@ --- * @@ -161,6 +153,25 @@ static void pfree(arena *a, void *p) { return; } /* Trivial */ static arena_ops pool_ops = { palloc, arena_fakerealloc, pfree, 0 }; +/* --- @pool_init@ --- * + * + * Arguments: @pool *p@ = pointer to the pool structure to initialize + * @arena *a@ = pointer to an arena to allocate memory from + * + * Returns: --- + * + * Use: Initializes a chunk of memory as a resource pool which is not + * a child of any other resource pool. + */ + +void pool_init(pool *p, arena *a) +{ + p->a.ops = &pool_ops; + p->c = 0; + p->r = 0; + p->pa = a; +} + /* --- @pool_create@ --- * * * Arguments: @arena *a@ = pointer to an arena to allocate memory from @@ -175,10 +186,8 @@ pool *pool_create(arena *a) { pool_chunk *c = 0; pool *p = doalloc(a, &c, sizeof(pool)); - p->a.ops = &pool_ops; + pool_init(p, a); p->c = c; - p->r = 0; - p->pa = a; return (p); } @@ -189,8 +198,9 @@ pool *pool_create(arena *a) * Returns: --- * * Use: Destroys a pool, freeing all of the resources within it. If - * this is a root pool, its memory will be deallocated; if it's - * a subpool, it is emptied and can be used again. + * this is a pool created by @pool_create@, its memory will be + * deallocated; if it's a subpool or it was initialized by + * @pool_init@, it is emptied and can be used again. */ void pool_destroy(pool *p) diff --git a/sub.c b/sub.c index ef43075..f065f9d 100644 --- a/sub.c +++ b/sub.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: sub.c,v 1.7 2003/05/18 15:10:20 mdw Exp $ + * $Id: sub.c,v 1.8 2003/10/12 14:44:46 mdw Exp $ * * Allocation of known-size blocks * @@ -30,6 +30,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: sub.c,v $ + * Revision 1.8 2003/10/12 14:44:46 mdw + * Various fixes. + * * Revision 1.7 2003/05/18 15:10:20 mdw * Add debugging mode which just uses the underlying arena. * @@ -179,6 +182,7 @@ void subarena_destroy(subarena *s) p = *(void **)q; A_FREE(s->a, q); } + s->bin[i] = 0; } #endif diff --git a/sub.h b/sub.h index 1b07703..87085ab 100644 --- a/sub.h +++ b/sub.h @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: sub.h,v 1.6 2000/06/17 10:35:51 mdw Exp $ + * $Id: sub.h,v 1.7 2003/10/12 14:44:46 mdw Exp $ * * Allocation of known-size blocks * @@ -30,6 +30,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: sub.h,v $ + * Revision 1.7 2003/10/12 14:44:46 mdw + * Various fixes. + * * Revision 1.6 2000/06/17 10:35:51 mdw * Major overhaul for arena support. * @@ -61,6 +64,10 @@ #include +#ifndef MLIB_ALIGN_H +# include "align.h" +#endif + #ifndef MLIB_ARENA_H # include "arena.h" #endif @@ -86,11 +93,10 @@ /* --- The granularity of bin buffers --- * * - * All blocks allocated by the binner are a multiple of this size. I've - * chosen @void *@ because I need to store @void *@ things in here. + * All blocks allocated by the binner are a multiple of this size. */ -#define SUB_GRANULE sizeof(void *) +#define SUB_GRANULE sizeof(union align) /* --- Finding the right bin for a given size --- * * -- [mdw]