chiark / gitweb /
Various fixes.
authormdw <mdw>
Sun, 12 Oct 2003 14:44:46 +0000 (14:44 +0000)
committermdw <mdw>
Sun, 12 Oct 2003 14:44:46 +0000 (14:44 +0000)
Makefile.am
man/crc32.3
man/pool.3
man/sub.3
pool.c
sub.c
sub.h

index 81b9515..081f74d 100644 (file)
@@ -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.in >da.ref
+       perl $(srcdir)/da-ref <da.in >da.ref.new
+       mv da.ref.new da.ref
 da.test: da.t da.in da.ref
        ./da.t <da.in >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.in >sym.ref
+       perl $(srcdir)/sym-ref <sym.in >sym.ref.new
+       mv sym.ref.new sym.ref
 sym.test: sym.t sym.in sym.ref
        ./sym.t <sym.in >sym.out
        cmp sym.out sym.ref
index c9e34ba..dda3ad0 100644 (file)
@@ -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, <mdw@nsict.org>
index 1e806bf..4c3dd5f 100644 (file)
@@ -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 <mLib/pool.h>"
 
+.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 ,
index e03fb1c..ef61110 100644 (file)
--- a/man/sub.3
+++ b/man/sub.3
 .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 <mLib/sub.h>"
 
+.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 (file)
--- 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 (file)
--- 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 (file)
--- 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.
  *
 
 #include <stdlib.h>
 
+#ifndef MLIB_ALIGN_H
+#  include "align.h"
+#endif
+
 #ifndef MLIB_ARENA_H
 #  include "arena.h"
 #endif
 
 /* --- 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 --- *
  *