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