pool: New function pool_strdup0.
[pspp-builds.git] / src / libpspp / pool.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2000 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include "pool.h"
19 #include <stdint.h>
20 #include <stdlib.h>
21 #include <libpspp/assertion.h>
22 #include "message.h"
23 #include "str.h"
24
25 #include "xalloc.h"
26
27 /* Fast, low-overhead memory block suballocator. */
28 struct pool
29   {
30     struct pool *parent;        /* Pool of which this pool is a subpool. */
31     struct pool_block *blocks;  /* Blocks owned by the pool. */
32     struct pool_gizmo *gizmos;  /* Other stuff owned by the pool. */
33   };
34
35 /* Pool block. */
36 struct pool_block
37   {
38     struct pool_block *prev;
39     struct pool_block *next;
40     size_t ofs;
41   };
42
43 /* Gizmo types. */
44 enum
45   {
46     POOL_GIZMO_MALLOC,
47     POOL_GIZMO_FILE,
48     POOL_GIZMO_SUBPOOL,
49     POOL_GIZMO_REGISTERED,
50   };
51
52 /* Pool routines can maintain objects (`gizmos') as well as doing
53    suballocation.
54    This structure is used to keep track of them. */
55 struct pool_gizmo
56   {
57     struct pool *pool;
58     struct pool_gizmo *prev;
59     struct pool_gizmo *next;
60
61     long serial;                /* Serial number. */
62     int type;                   /* Type of this gizmo. */
63
64     /* Type-dependent info. */
65     union
66       {
67         FILE *file;             /* POOL_GIZMO_FILE. */
68         struct pool *subpool;   /* POOL_GIZMO_SUBPOOL. */
69
70         /* POOL_GIZMO_REGISTERED. */
71         struct
72           {
73             void (*free) (void *p);
74             void *p;
75           }
76         registered;
77       }
78     p;
79   };
80
81 /* Rounds X up to the next multiple of Y. */
82 #ifndef ROUND_UP
83 #define ROUND_UP(X, Y)                          \
84         (((X) + ((Y) - 1)) / (Y) * (Y))
85 #endif
86
87 /* Types that provide typically useful alignment sizes. */
88 union align
89   {
90     void *op;
91     void (*fp) (void);
92     long l;
93     double d;
94   };
95
96 /* This should be the alignment size used by malloc().  The size of
97    the union above is correct, if not optimal, in all known cases. */
98 #define ALIGN_SIZE sizeof (union align)
99
100 /* DISCRETE_BLOCKS may be declared as nonzero to prevent
101    suballocation of blocks.  This is useful under memory
102    debuggers like valgrind because it allows the source location
103    of bugs to be more accurately pinpointed.
104
105    On the other hand, if we're testing the library, then we want to
106    test the library's real functionality, not its crippled, slow,
107    simplified functionality. */
108 /*#define DISCRETE_BLOCKS 1*/
109
110 /* Size of each block allocated in the pool, in bytes.
111    Should be at least 1k. */
112 #ifndef BLOCK_SIZE
113 #define BLOCK_SIZE 1024
114 #endif
115
116
117 /* Sizes of some structures with alignment padding included. */
118 #define POOL_BLOCK_SIZE ROUND_UP (sizeof (struct pool_block), ALIGN_SIZE)
119 #define POOL_GIZMO_SIZE ROUND_UP (sizeof (struct pool_gizmo), ALIGN_SIZE)
120 #define POOL_SIZE ROUND_UP (sizeof (struct pool), ALIGN_SIZE)
121
122 /* Serial number used to keep track of gizmos for mark/release. */
123 static long serial = 0;
124
125 /* Prototypes. */
126 static void add_gizmo (struct pool *, struct pool_gizmo *);
127 static void free_gizmo (struct pool_gizmo *);
128 static void free_all_gizmos (struct pool *pool);
129 static void delete_gizmo (struct pool *, struct pool_gizmo *);
130 static void check_gizmo (struct pool *, struct pool_gizmo *);
131 \f
132 /* General routines. */
133
134 /* Creates and returns a new memory pool, which allows malloc()'d
135    blocks to be suballocated in a time- and space-efficient manner.
136    The entire contents of the memory pool are freed at once.
137
138    In addition, other objects can be associated with a memory pool.
139    These are released when the pool is destroyed. */
140 struct pool *
141 pool_create (void)
142 {
143   struct pool_block *block;
144   struct pool *pool;
145
146   block = xmalloc (BLOCK_SIZE);
147   block->prev = block->next = block;
148   block->ofs = POOL_BLOCK_SIZE + POOL_SIZE;
149
150   pool = (struct pool *) (((char *) block) + POOL_BLOCK_SIZE);
151   pool->parent = NULL;
152   pool->blocks = block;
153   pool->gizmos = NULL;
154
155   return pool;
156 }
157
158 /* Creates a pool, allocates a block STRUCT_SIZE bytes in
159    length from it, stores the pool's address at offset
160    POOL_MEMBER_OFFSET within the block, and returns the allocated
161    block.
162
163    Meant for use indirectly via pool_create_container(). */
164 void *
165 pool_create_at_offset (size_t struct_size, size_t pool_member_offset)
166 {
167   struct pool *pool;
168   char *struct_;
169
170   assert (struct_size >= sizeof pool);
171   assert (pool_member_offset <= struct_size - sizeof pool);
172
173   pool = pool_create ();
174   struct_ = pool_alloc (pool, struct_size);
175   *(struct pool **) (struct_ + pool_member_offset) = pool;
176   return struct_;
177 }
178
179 /* Destroy the specified pool, including all subpools. */
180 void
181 pool_destroy (struct pool *pool)
182 {
183   if (pool == NULL)
184     return;
185
186   /* Remove this pool from its parent's list of gizmos. */
187   if (pool->parent)
188     delete_gizmo (pool->parent, (void *) (((char *) pool) + POOL_SIZE));
189
190   free_all_gizmos (pool);
191
192   /* Free all the memory. */
193   {
194     struct pool_block *cur, *next;
195
196     pool->blocks->prev->next = NULL;
197     for (cur = pool->blocks; cur; cur = next)
198       {
199         next = cur->next;
200         free (cur);
201       }
202   }
203 }
204
205 /* Release all the memory and gizmos in POOL.
206    Blocks are not given back with free() but kept for later
207    allocations.  To give back memory, use a subpool instead. */
208 void
209 pool_clear (struct pool *pool)
210 {
211   free_all_gizmos (pool);
212
213   /* Zero out block sizes. */
214   {
215     struct pool_block *cur;
216
217     cur = pool->blocks;
218     do
219       {
220         cur->ofs = POOL_BLOCK_SIZE;
221         if ((char *) cur + POOL_BLOCK_SIZE == (char *) pool)
222           {
223             cur->ofs += POOL_SIZE;
224             if (pool->parent != NULL)
225               cur->ofs += POOL_GIZMO_SIZE;
226           }
227         cur = cur->next;
228       }
229     while (cur != pool->blocks);
230   }
231 }
232 \f
233 /* Suballocation routines. */
234
235 /* Allocates a memory region AMT bytes in size from POOL and returns a
236    pointer to the region's start.
237    The region is properly aligned for storing any object. */
238 void *
239 pool_alloc (struct pool *pool, size_t amt)
240 {
241   assert (pool != NULL);
242
243   if (amt == 0)
244     return NULL;
245
246 #ifndef DISCRETE_BLOCKS
247   if (amt <= MAX_SUBALLOC)
248     {
249       /* If there is space in this block, take it. */
250       struct pool_block *b = pool->blocks;
251       b->ofs = ROUND_UP (b->ofs, ALIGN_SIZE);
252       if (b->ofs + amt <= BLOCK_SIZE)
253         {
254           void *const p = ((char *) b) + b->ofs;
255           b->ofs += amt;
256           return p;
257         }
258
259       /* No space in this block, so we must make other
260          arrangements. */
261       if (b->next->ofs == 0)
262         {
263           /* The next block is empty.  Use it. */
264           b = b->next;
265           b->ofs = POOL_BLOCK_SIZE;
266           if ((char *) b + POOL_BLOCK_SIZE == (char *) pool)
267             b->ofs += POOL_SIZE;
268         }
269       else
270         {
271           /* Create a new block at the start of the list. */
272           b = xmalloc (BLOCK_SIZE);
273           b->next = pool->blocks;
274           b->prev = pool->blocks->prev;
275           b->ofs = POOL_BLOCK_SIZE;
276           pool->blocks->prev->next = b;
277           pool->blocks->prev = b;
278         }
279       pool->blocks = b;
280
281       /* Allocate space from B. */
282       b->ofs += amt;
283       return ((char *) b) + b->ofs - amt;
284     }
285   else
286 #endif
287     return pool_malloc (pool, amt);
288 }
289
290 /* Allocates a memory region AMT bytes in size from POOL and
291    returns a pointer to the region's start.  The region is not
292    necessarily aligned, so it is most suitable for storing
293    strings. */
294 void *
295 pool_alloc_unaligned (struct pool *pool, size_t amt)
296 {
297   assert (pool != NULL);
298
299 #ifndef DISCRETE_BLOCKS
300   /* Strings need not be aligned on any boundary, but some
301      operations may be more efficient when they are.  However,
302      that's only going to help with reasonably long strings. */
303   if (amt < ALIGN_SIZE)
304     {
305       if (amt == 0)
306         return NULL;
307       else
308         {
309           struct pool_block *const b = pool->blocks;
310
311           if (b->ofs + amt <= BLOCK_SIZE)
312             {
313               void *p = ((char *) b) + b->ofs;
314               b->ofs += amt;
315               return p;
316             }
317         }
318     }
319 #endif
320
321   return pool_alloc (pool, amt);
322 }
323
324 /* Allocates a memory region N * S bytes in size from POOL and
325    returns a pointer to the region's start.
326    N must be nonnegative, S must be positive.
327    Terminates the program if the memory cannot be obtained,
328    including the case where N * S overflows the range of size_t. */
329 void *
330 pool_nalloc (struct pool *pool, size_t n, size_t s)
331 {
332   if (xalloc_oversized (n, s))
333     xalloc_die ();
334   return pool_alloc (pool, n * s);
335 }
336
337 /* Allocates SIZE bytes in POOL, copies BUFFER into it, and
338    returns the new copy. */
339 void *
340 pool_clone (struct pool *pool, const void *buffer, size_t size)
341 {
342   void *block = pool_alloc (pool, size);
343   memcpy (block, buffer, size);
344   return block;
345 }
346
347 /* Allocates SIZE bytes of unaligned data in POOL, copies BUFFER
348    into it, and returns the new copy. */
349 void *
350 pool_clone_unaligned (struct pool *pool, const void *buffer, size_t size)
351 {
352   void *block = pool_alloc_unaligned (pool, size);
353   memcpy (block, buffer, size);
354   return block;
355 }
356
357 /* Duplicates null-terminated STRING, within POOL, and returns a
358    pointer to the duplicate.  For use only with strings, because
359    the returned pointere may not be aligned properly for other
360    types. */
361 char *
362 pool_strdup (struct pool *pool, const char *string)
363 {
364   return pool_clone_unaligned (pool, string, strlen (string) + 1);
365 }
366
367 /* Duplicates the SIZE bytes of STRING, plus a trailing 0 byte,
368    and returns a pointer to the duplicate.  For use only with
369    strings, because the returned pointere may not be aligned
370    properly for other types. */
371 char *
372 pool_strdup0 (struct pool *pool, const char *string, size_t size)
373 {
374   char *new_string = pool_alloc_unaligned (pool, size + 1);
375   memcpy (new_string, string, size);
376   new_string[size] = '\0';
377   return new_string;
378 }
379
380 /* Formats FORMAT with the given ARGS in memory allocated from
381    POOL and returns the formatted string. */
382 char *
383 pool_vasprintf (struct pool *pool, const char *format, va_list args_)
384 {
385   struct pool_block *b;
386   va_list args;
387   int needed, avail;
388   char *s;
389
390   va_copy (args, args_);
391   b = pool->blocks;
392   avail = BLOCK_SIZE - b->ofs;
393   s = ((char *) b) + b->ofs;
394   needed = vsnprintf (s, avail, format, args);
395   va_end (args);
396
397   if (needed >= 0)
398     {
399       if (needed < avail)
400         {
401           /* Success.  Reserve the space that was actually used. */
402           b->ofs += needed + 1;
403         }
404       else
405         {
406           /* Failure, but now we know how much space is needed.
407              Allocate that much and reformat. */
408           s = pool_alloc (pool, needed + 1);
409
410           va_copy (args, args_);
411           vsprintf (s, format, args);
412           va_end (args);
413         }
414     }
415   else
416     {
417       /* Some old libc's returned -1 when the destination string
418          was too short.  This should be uncommon these days and
419          it's a rare case anyhow.  Use the easiest solution: punt
420          to dynamic allocation. */
421       va_copy (args, args_);
422       s = xvasprintf (format, args);
423       va_end (args);
424
425       pool_register (pool, free, s);
426     }
427
428   return s;
429 }
430
431 /* Formats FORMAT in memory allocated from POOL
432    and returns the formatted string. */
433 char *
434 pool_asprintf (struct pool *pool, const char *format, ...)
435 {
436   va_list args;
437   char *string;
438
439   va_start (args, format);
440   string = pool_vasprintf (pool, format, args);
441   va_end (args);
442
443   return string;
444 }
445 \f
446 /* Standard allocation routines. */
447
448 /* Allocates AMT bytes using malloc(), to be managed by POOL, and
449    returns a pointer to the beginning of the block.
450    If POOL is a null pointer, then allocates a normal memory block
451    with xmalloc().  */
452 void *
453 pool_malloc (struct pool *pool, size_t amt)
454 {
455   if (pool != NULL)
456     {
457       if (amt != 0)
458         {
459           struct pool_gizmo *g = xmalloc (amt + POOL_GIZMO_SIZE);
460           g->type = POOL_GIZMO_MALLOC;
461           add_gizmo (pool, g);
462
463           return ((char *) g) + POOL_GIZMO_SIZE;
464         }
465       else
466         return NULL;
467     }
468   else
469     return xmalloc (amt);
470 }
471
472 /* Allocates and returns N elements of S bytes each, to be
473    managed by POOL.
474    If POOL is a null pointer, then allocates a normal memory block
475    with malloc().
476    N must be nonnegative, S must be positive.
477    Terminates the program if the memory cannot be obtained,
478    including the case where N * S overflows the range of size_t. */
479 void *
480 pool_nmalloc (struct pool *pool, size_t n, size_t s)
481 {
482   if (xalloc_oversized (n, s))
483     xalloc_die ();
484   return pool_malloc (pool, n * s);
485 }
486
487 /* Allocates AMT bytes using malloc(), to be managed by POOL,
488    zeros the block, and returns a pointer to the beginning of the
489    block.
490    If POOL is a null pointer, then allocates a normal memory block
491    with xmalloc().  */
492 void *
493 pool_zalloc (struct pool *pool, size_t amt)
494 {
495   void *p = pool_malloc (pool, amt);
496   memset (p, 0, amt);
497   return p;
498 }
499
500 /* Allocates and returns N elements of S bytes each, to be
501    managed by POOL, and zeros the block.
502    If POOL is a null pointer, then allocates a normal memory block
503    with malloc().
504    N must be nonnegative, S must be positive.
505    Terminates the program if the memory cannot be obtained,
506    including the case where N * S overflows the range of size_t. */
507 void *
508 pool_calloc (struct pool *pool, size_t n, size_t s)
509 {
510   void *p = pool_nmalloc (pool, n, s);
511   memset (p, 0, n * s);
512   return p;
513 }
514
515 /* Changes the allocation size of the specified memory block P managed
516    by POOL to AMT bytes and returns a pointer to the beginning of the
517    block.
518    If POOL is a null pointer, then the block is reallocated in the
519    usual way with realloc(). */
520 void *
521 pool_realloc (struct pool *pool, void *p, size_t amt)
522 {
523   if (pool != NULL)
524     {
525       if (p != NULL)
526         {
527           if (amt != 0)
528             {
529               struct pool_gizmo *g = (void *) (((char *) p) - POOL_GIZMO_SIZE);
530               check_gizmo (pool, g);
531
532               g = xrealloc (g, amt + POOL_GIZMO_SIZE);
533               if (g->next)
534                 g->next->prev = g;
535               if (g->prev)
536                 g->prev->next = g;
537               else
538                 pool->gizmos = g;
539               check_gizmo (pool, g);
540
541               return ((char *) g) + POOL_GIZMO_SIZE;
542             }
543           else
544             {
545               pool_free (pool, p);
546               return NULL;
547             }
548         }
549       else
550         return pool_malloc (pool, amt);
551     }
552   else
553     return xrealloc (p, amt);
554 }
555
556 /* Changes the allocation size of the specified memory block P
557    managed by POOL to N * S bytes and returns a pointer to the
558    beginning of the block.
559    N must be nonnegative, S must be positive.
560    If POOL is a null pointer, then the block is reallocated in
561    the usual way with xrealloc().
562    Terminates the program if the memory cannot be obtained,
563    including the case where N * S overflows the range of size_t. */
564 void *
565 pool_nrealloc (struct pool *pool, void *p, size_t n, size_t s)
566 {
567   if (xalloc_oversized (n, s))
568     xalloc_die ();
569   return pool_realloc (pool, p, n * s);
570 }
571
572 /* If P is null, allocate a block of at least *PN such objects;
573    otherwise, reallocate P so that it contains more than *PN
574    objects each of S bytes.  *PN must be nonzero unless P is
575    null, and S must be nonzero.  Set *PN to the new number of
576    objects, and return the pointer to the new block.  *PN is
577    never set to zero, and the returned pointer is never null.
578
579    The block returned is managed by POOL.  If POOL is a null
580    pointer, then the block is reallocated in the usual way with
581    x2nrealloc().
582
583    Terminates the program if the memory cannot be obtained,
584    including the case where the memory required overflows the
585    range of size_t.
586
587    Repeated reallocations are guaranteed to make progress, either by
588    allocating an initial block with a nonzero size, or by allocating a
589    larger block.
590
591    In the following implementation, nonzero sizes are doubled so that
592    repeated reallocations have O(N log N) overall cost rather than
593    O(N**2) cost, but the specification for this function does not
594    guarantee that sizes are doubled.
595
596    Here is an example of use:
597
598      int *p = NULL;
599      struct pool *pool;
600      size_t used = 0;
601      size_t allocated = 0;
602
603      void
604      append_int (int value)
605        {
606          if (used == allocated)
607            p = pool_2nrealloc (pool, p, &allocated, sizeof *p);
608          p[used++] = value;
609        }
610
611    This causes x2nrealloc to allocate a block of some nonzero size the
612    first time it is called.
613
614    To have finer-grained control over the initial size, set *PN to a
615    nonzero value before calling this function with P == NULL.  For
616    example:
617
618      int *p = NULL;
619      struct pool *pool;
620      size_t used = 0;
621      size_t allocated = 0;
622      size_t allocated1 = 1000;
623
624      void
625      append_int (int value)
626        {
627          if (used == allocated)
628            {
629              p = pool_2nrealloc (pool, p, &allocated1, sizeof *p);
630              allocated = allocated1;
631            }
632          p[used++] = value;
633        }
634
635    This function implementation is from gnulib. */
636 void *
637 pool_2nrealloc (struct pool *pool, void *p, size_t *pn, size_t s)
638 {
639   size_t n = *pn;
640
641   if (p == NULL)
642     {
643       if (n == 0)
644         {
645           /* The approximate size to use for initial small allocation
646              requests, when the invoking code specifies an old size of
647              zero.  64 bytes is the largest "small" request for the
648              GNU C library malloc.  */
649           enum { DEFAULT_MXFAST = 64 };
650
651           n = DEFAULT_MXFAST / s;
652           n += !n;
653         }
654     }
655   else
656     {
657       if (SIZE_MAX / 2 / s < n)
658         xalloc_die ();
659       n *= 2;
660     }
661
662   *pn = n;
663   return pool_realloc (pool, p, n * s);
664 }
665
666 /* Frees block P managed by POOL.
667    If POOL is a null pointer, then the block is freed as usual with
668    free(). */
669 void
670 pool_free (struct pool *pool, void *p)
671 {
672   if (pool != NULL && p != NULL)
673     {
674       struct pool_gizmo *g = (void *) (((char *) p) - POOL_GIZMO_SIZE);
675       check_gizmo (pool, g);
676       delete_gizmo (pool, g);
677       free (g);
678     }
679   else
680     free (p);
681 }
682 \f
683 /* Gizmo allocations. */
684
685 /* Creates and returns a pool as a subpool of POOL.
686    The subpool will be destroyed automatically when POOL is destroyed.
687    It may also be destroyed explicitly in advance. */
688 struct pool *
689 pool_create_subpool (struct pool *pool)
690 {
691   struct pool *subpool;
692   struct pool_gizmo *g;
693
694   assert (pool != NULL);
695   subpool = pool_create ();
696   subpool->parent = pool;
697
698   g = (void *) (((char *) subpool->blocks) + subpool->blocks->ofs);
699   subpool->blocks->ofs += POOL_GIZMO_SIZE;
700
701   g->type = POOL_GIZMO_SUBPOOL;
702   g->p.subpool = subpool;
703
704   add_gizmo (pool, g);
705
706   return subpool;
707 }
708
709 /* Makes SUBPOOL a subpool of POOL.
710    SUBPOOL must not already have a parent pool.
711    The subpool will be destroyed automatically when POOL is destroyed.
712    It may also be destroyed explicitly in advance. */
713 void
714 pool_add_subpool (struct pool *pool, struct pool *subpool)
715 {
716   struct pool_gizmo *g;
717
718   assert (pool != NULL);
719   assert (subpool != NULL);
720   assert (subpool->parent == NULL);
721
722   g = pool_alloc (subpool, sizeof *g);
723   g->type = POOL_GIZMO_SUBPOOL;
724   g->p.subpool = subpool;
725   add_gizmo (pool, g);
726
727   subpool->parent = pool;
728 }
729
730 /* Opens file FILE_NAME with mode MODE and returns a handle to it
731    if successful or a null pointer if not.
732    The file will be closed automatically when POOL is destroyed, or it
733    may be closed explicitly in advance using pool_fclose(), or
734    detached from the pool with pool_detach_file(). */
735 FILE *
736 pool_fopen (struct pool *pool, const char *file_name, const char *mode)
737 {
738   FILE *f;
739
740   assert (pool && file_name && mode);
741   f = fopen (file_name, mode);
742   if (f != NULL)
743     pool_attach_file (pool, f);
744
745   return f;
746 }
747
748 /* Closes file FILE managed by POOL.
749    Returns 0 if successful, EOF if an I/O error occurred. */
750 int
751 pool_fclose (struct pool *pool, FILE *file)
752 {
753   assert (pool && file);
754   pool_detach_file (pool, file);
755   return fclose (file);
756 }
757
758 /* Creates a temporary file with tmpfile() and returns a handle to it
759    if successful or a null pointer if not.
760    The file will be closed automatically when POOL is destroyed, or it
761    may be closed explicitly in advance using pool_fclose(), or
762    detached from the pool with pool_detach_file(). */
763 FILE *
764 pool_tmpfile (struct pool *pool)
765 {
766   FILE *file = tmpfile ();
767   if (file != NULL)
768     pool_attach_file (pool, file);
769   return file;
770 }
771
772 /* Attaches FILE to POOL.
773    The file will be closed automatically when POOL is destroyed, or it
774    may be closed explicitly in advance using pool_fclose(), or
775    detached from the pool with pool_detach_file(). */
776 void
777 pool_attach_file (struct pool *pool, FILE *file)
778 {
779   struct pool_gizmo *g = pool_alloc (pool, sizeof *g);
780   g->type = POOL_GIZMO_FILE;
781   g->p.file = file;
782   add_gizmo (pool, g);
783 }
784
785 /* Detaches FILE from POOL. */
786 void
787 pool_detach_file (struct pool *pool, FILE *file)
788 {
789   struct pool_gizmo *g;
790
791   for (g = pool->gizmos; g; g = g->next)
792     if (g->type == POOL_GIZMO_FILE && g->p.file == file)
793       {
794         delete_gizmo (pool, g);
795         return;
796       }
797 }
798 \f
799 /* Registers FREE to be called with argument P.
800    P should be unique among those registered in POOL so that it can be
801    uniquely identified by pool_unregister().
802    If not unregistered, FREE will be called with argument P when POOL
803    is destroyed. */
804 void
805 pool_register (struct pool *pool, void (*free) (void *), void *p)
806 {
807   assert (pool && free && p);
808
809   {
810     struct pool_gizmo *g = pool_alloc (pool, sizeof *g);
811     g->type = POOL_GIZMO_REGISTERED;
812     g->p.registered.free = free;
813     g->p.registered.p = p;
814     add_gizmo (pool, g);
815   }
816 }
817
818 /* Unregisters previously registered P from POOL.
819    Returns true only if P was found to be registered in POOL. */
820 bool
821 pool_unregister (struct pool *pool, void *p)
822 {
823   assert (pool && p);
824
825   {
826     struct pool_gizmo *g;
827
828     for (g = pool->gizmos; g; g = g->next)
829       if (g->type == POOL_GIZMO_REGISTERED && g->p.registered.p == p)
830         {
831           delete_gizmo (pool, g);
832           return true;
833         }
834   }
835
836   return false;
837 }
838 \f
839 /* Partial freeing. */
840
841 /* Notes the state of POOL into MARK so that it may be restored
842    by a call to pool_release(). */
843 void
844 pool_mark (struct pool *pool, struct pool_mark *mark)
845 {
846   assert (pool && mark);
847
848   mark->block = pool->blocks;
849   mark->ofs = pool->blocks->ofs;
850
851   mark->serial = serial;
852 }
853
854 /* Restores to POOL the state recorded in MARK.
855    Emptied blocks are not given back with free() but kept for
856    later allocations.  To get that behavior, use a subpool
857    instead. */
858 void
859 pool_release (struct pool *pool, const struct pool_mark *mark)
860 {
861   assert (pool && mark);
862
863   {
864     struct pool_gizmo *cur, *next;
865
866     for (cur = pool->gizmos; cur && cur->serial >= mark->serial; cur = next)
867       {
868         next = cur->next;
869         free_gizmo (cur);
870       }
871
872     if (cur != NULL)
873       {
874         cur->prev = NULL;
875         pool->gizmos = cur;
876       }
877     else
878       pool->gizmos = NULL;
879   }
880
881   {
882     struct pool_block *cur;
883
884     for (cur = pool->blocks; cur != mark->block; cur = cur->next)
885       {
886         cur->ofs = POOL_BLOCK_SIZE;
887         if ((char *) cur + POOL_BLOCK_SIZE == (char *) pool)
888           {
889             cur->ofs += POOL_SIZE;
890             if (pool->parent != NULL)
891               cur->ofs += POOL_GIZMO_SIZE;
892           }
893       }
894     pool->blocks = mark->block;
895     pool->blocks->ofs = mark->ofs;
896   }
897 }
898 \f
899 /* Private functions. */
900
901 /* Adds GIZMO at the beginning of POOL's gizmo list. */
902 static void
903 add_gizmo (struct pool *pool, struct pool_gizmo *gizmo)
904 {
905   assert (pool && gizmo);
906
907   gizmo->pool = pool;
908   gizmo->next = pool->gizmos;
909   gizmo->prev = NULL;
910   if (pool->gizmos)
911     pool->gizmos->prev = gizmo;
912   pool->gizmos = gizmo;
913
914   gizmo->serial = serial++;
915
916   check_gizmo (pool, gizmo);
917 }
918
919 /* Removes GIZMO from POOL's gizmo list. */
920 static void
921 delete_gizmo (struct pool *pool, struct pool_gizmo *gizmo)
922 {
923   assert (pool && gizmo);
924
925   check_gizmo (pool, gizmo);
926
927   if (gizmo->prev)
928     gizmo->prev->next = gizmo->next;
929   else
930     pool->gizmos = gizmo->next;
931   if (gizmo->next)
932     gizmo->next->prev = gizmo->prev;
933 }
934
935 /* Frees any of GIZMO's internal state.
936    GIZMO's data must not be referenced after calling this function. */
937 static void
938 free_gizmo (struct pool_gizmo *gizmo)
939 {
940   assert (gizmo != NULL);
941
942   switch (gizmo->type)
943     {
944     case POOL_GIZMO_MALLOC:
945       free (gizmo);
946       break;
947     case POOL_GIZMO_FILE:
948       fclose (gizmo->p.file);   /* Ignore errors. */
949       break;
950     case POOL_GIZMO_SUBPOOL:
951       gizmo->p.subpool->parent = NULL;
952       pool_destroy (gizmo->p.subpool);
953       break;
954     case POOL_GIZMO_REGISTERED:
955       gizmo->p.registered.free (gizmo->p.registered.p);
956       break;
957     default:
958       NOT_REACHED ();
959     }
960 }
961
962 /* Free all the gizmos in POOL. */
963 static void
964 free_all_gizmos (struct pool *pool)
965 {
966   struct pool_gizmo *cur, *next;
967
968   for (cur = pool->gizmos; cur; cur = next)
969     {
970       next = cur->next;
971       free_gizmo (cur);
972     }
973   pool->gizmos = NULL;
974 }
975
976 static void
977 check_gizmo (struct pool *p, struct pool_gizmo *g)
978 {
979   assert (g->pool == p);
980   assert (g->next == NULL || g->next->prev == g);
981   assert ((g->prev != NULL && g->prev->next == g)
982           || (g->prev == NULL && p->gizmos == g));
983
984 }