1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2000, 2010, 2011 Free Software Foundation, Inc.
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.
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.
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/>. */
19 #include "libpspp/pool.h"
24 #include "libpspp/assertion.h"
25 #include "libpspp/message.h"
26 #include "libpspp/temp-file.h"
27 #include "libpspp/str.h"
29 #include "gl/xalloc.h"
31 /* Fast, low-overhead memory block suballocator. */
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. */
42 struct pool_block *prev;
43 struct pool_block *next;
54 POOL_GIZMO_REGISTERED,
57 /* Pool routines can maintain objects (`gizmos') as well as doing
59 This structure is used to keep track of them. */
63 struct pool_gizmo *prev;
64 struct pool_gizmo *next;
66 long serial; /* Serial number. */
67 int type; /* Type of this gizmo. */
69 /* Type-dependent info. */
72 FILE *file; /* POOL_GIZMO_FILE, POOL_GIZMO_TEMP_FILE. */
73 struct pool *subpool; /* POOL_GIZMO_SUBPOOL. */
75 /* POOL_GIZMO_REGISTERED. */
78 void (*free) (void *p);
86 /* Rounds X up to the next multiple of Y. */
88 #define ROUND_UP(X, Y) \
89 (((X) + ((Y) - 1)) / (Y) * (Y))
92 /* Types that provide typically useful alignment sizes. */
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)
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.
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*/
115 /* Size of each block allocated in the pool, in bytes.
116 Should be at least 1k. */
118 #define BLOCK_SIZE 1024
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)
127 /* Serial number used to keep track of gizmos for mark/release. */
128 static long serial = 0;
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 *);
137 /* General routines. */
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.
143 In addition, other objects can be associated with a memory pool.
144 These are released when the pool is destroyed. */
148 struct pool_block *block;
151 block = xmalloc (BLOCK_SIZE);
152 block->prev = block->next = block;
153 block->ofs = POOL_BLOCK_SIZE + POOL_SIZE;
155 pool = (struct pool *) (((char *) block) + POOL_BLOCK_SIZE);
157 pool->blocks = block;
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
168 Meant for use indirectly via pool_create_container(). */
170 pool_create_at_offset (size_t struct_size, size_t pool_member_offset)
175 assert (struct_size >= sizeof pool);
176 assert (pool_member_offset <= struct_size - sizeof pool);
178 pool = pool_create ();
179 struct_ = pool_alloc (pool, struct_size);
180 *(struct pool **) (struct_ + pool_member_offset) = pool;
184 /* Destroy the specified pool, including all subpools. */
186 pool_destroy (struct pool *pool)
191 /* Remove this pool from its parent's list of gizmos. */
193 delete_gizmo (pool->parent, (void *) (((char *) pool) + POOL_SIZE));
195 free_all_gizmos (pool);
197 /* Free all the memory. */
199 struct pool_block *cur, *next;
201 pool->blocks->prev->next = NULL;
202 for (cur = pool->blocks; cur; cur = next)
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. */
214 pool_clear (struct pool *pool)
216 free_all_gizmos (pool);
218 /* Zero out block sizes. */
220 struct pool_block *cur;
225 cur->ofs = POOL_BLOCK_SIZE;
226 if ((char *) cur + POOL_BLOCK_SIZE == (char *) pool)
228 cur->ofs += POOL_SIZE;
229 if (pool->parent != NULL)
230 cur->ofs += POOL_GIZMO_SIZE;
234 while (cur != pool->blocks);
238 /* Suballocation routines. */
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. */
244 pool_alloc (struct pool *pool, size_t amt)
246 assert (pool != NULL);
251 #ifndef DISCRETE_BLOCKS
252 if (amt <= MAX_SUBALLOC)
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)
259 void *const p = ((char *) b) + b->ofs;
264 /* No space in this block, so we must make other
266 if (b->next->ofs == 0)
268 /* The next block is empty. Use it. */
270 b->ofs = POOL_BLOCK_SIZE;
271 if ((char *) b + POOL_BLOCK_SIZE == (char *) pool)
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;
286 /* Allocate space from B. */
288 return ((char *) b) + b->ofs - amt;
292 return pool_malloc (pool, amt);
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
300 pool_alloc_unaligned (struct pool *pool, size_t amt)
303 return xmalloc (amt);
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)
315 struct pool_block *const b = pool->blocks;
317 if (b->ofs + amt <= BLOCK_SIZE)
319 void *p = ((char *) b) + b->ofs;
327 return pool_alloc (pool, amt);
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. */
336 pool_nalloc (struct pool *pool, size_t n, size_t s)
338 if (xalloc_oversized (n, s))
340 return pool_alloc (pool, n * s);
343 /* Allocates SIZE bytes in POOL, copies BUFFER into it, and
344 returns the new copy. */
346 pool_clone (struct pool *pool, const void *buffer, size_t size)
348 void *block = pool_alloc (pool, size);
349 memcpy (block, buffer, size);
353 /* Allocates SIZE bytes of unaligned data in POOL, copies BUFFER
354 into it, and returns the new copy. */
356 pool_clone_unaligned (struct pool *pool, const void *buffer, size_t size)
358 void *block = pool_alloc_unaligned (pool, size);
359 memcpy (block, buffer, size);
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
368 pool_strdup (struct pool *pool, const char *string)
370 return pool_clone_unaligned (pool, string, strlen (string) + 1);
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. */
378 pool_strdup0 (struct pool *pool, const char *string, size_t size)
380 char *new_string = pool_alloc_unaligned (pool, size + 1);
381 memcpy (new_string, string, size);
382 new_string[size] = '\0';
386 /* Formats FORMAT with the given ARGS in memory allocated from
387 POOL and returns the formatted string. */
389 pool_vasprintf (struct pool *pool, const char *format, va_list args_)
391 struct pool_block *b;
396 va_copy (args, args_);
398 avail = BLOCK_SIZE - b->ofs;
399 s = ((char *) b) + b->ofs;
400 needed = vsnprintf (s, avail, format, args);
407 /* Success. Reserve the space that was actually used. */
408 b->ofs += needed + 1;
412 /* Failure, but now we know how much space is needed.
413 Allocate that much and reformat. */
414 s = pool_alloc (pool, needed + 1);
416 va_copy (args, args_);
417 vsprintf (s, format, args);
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);
431 pool_register (pool, free, s);
437 /* Formats FORMAT in memory allocated from POOL
438 and returns the formatted string. */
440 pool_asprintf (struct pool *pool, const char *format, ...)
445 va_start (args, format);
446 string = pool_vasprintf (pool, format, args);
452 /* Standard allocation routines. */
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
459 pool_malloc (struct pool *pool, size_t amt)
465 struct pool_gizmo *g = xmalloc (amt + POOL_GIZMO_SIZE);
466 g->type = POOL_GIZMO_MALLOC;
469 return ((char *) g) + POOL_GIZMO_SIZE;
475 return xmalloc (amt);
478 /* Allocates and returns N elements of S bytes each, to be
480 If POOL is a null pointer, then allocates a normal memory block
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. */
486 pool_nmalloc (struct pool *pool, size_t n, size_t s)
488 if (xalloc_oversized (n, s))
490 return pool_malloc (pool, n * s);
493 /* Allocates AMT bytes using malloc(), to be managed by POOL,
494 zeros the block, and returns a pointer to the beginning of the
496 If POOL is a null pointer, then allocates a normal memory block
499 pool_zalloc (struct pool *pool, size_t amt)
501 void *p = pool_malloc (pool, amt);
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
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. */
514 pool_calloc (struct pool *pool, size_t n, size_t s)
516 void *p = pool_nmalloc (pool, n, s);
517 memset (p, 0, n * s);
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
524 If POOL is a null pointer, then the block is reallocated in the
525 usual way with realloc(). */
527 pool_realloc (struct pool *pool, void *p, size_t amt)
535 struct pool_gizmo *g = (void *) (((char *) p) - POOL_GIZMO_SIZE);
536 check_gizmo (pool, g);
538 g = xrealloc (g, amt + POOL_GIZMO_SIZE);
545 check_gizmo (pool, g);
547 return ((char *) g) + POOL_GIZMO_SIZE;
556 return pool_malloc (pool, amt);
559 return xrealloc (p, amt);
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. */
571 pool_nrealloc (struct pool *pool, void *p, size_t n, size_t s)
573 if (xalloc_oversized (n, s))
575 return pool_realloc (pool, p, n * s);
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.
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
589 Terminates the program if the memory cannot be obtained,
590 including the case where the memory required overflows the
593 Repeated reallocations are guaranteed to make progress, either by
594 allocating an initial block with a nonzero size, or by allocating a
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.
602 Here is an example of use:
607 size_t allocated = 0;
610 append_int (int value)
612 if (used == allocated)
613 p = pool_2nrealloc (pool, p, &allocated, sizeof *p);
617 This causes x2nrealloc to allocate a block of some nonzero size the
618 first time it is called.
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
627 size_t allocated = 0;
628 size_t allocated1 = 1000;
631 append_int (int value)
633 if (used == allocated)
635 p = pool_2nrealloc (pool, p, &allocated1, sizeof *p);
636 allocated = allocated1;
641 This function implementation is from gnulib. */
643 pool_2nrealloc (struct pool *pool, void *p, size_t *pn, size_t s)
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 };
657 n = DEFAULT_MXFAST / s;
663 if (SIZE_MAX / 2 / s < n)
669 return pool_realloc (pool, p, n * s);
672 /* Frees block P managed by POOL.
673 If POOL is a null pointer, then the block is freed as usual with
676 pool_free (struct pool *pool, void *p)
678 if (pool != NULL && p != NULL)
680 struct pool_gizmo *g = (void *) (((char *) p) - POOL_GIZMO_SIZE);
681 check_gizmo (pool, g);
682 delete_gizmo (pool, g);
689 /* Gizmo allocations. */
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. */
695 pool_create_subpool (struct pool *pool)
697 struct pool *subpool;
698 struct pool_gizmo *g;
700 assert (pool != NULL);
701 subpool = pool_create ();
702 subpool->parent = pool;
704 g = (void *) (((char *) subpool->blocks) + subpool->blocks->ofs);
705 subpool->blocks->ofs += POOL_GIZMO_SIZE;
707 g->type = POOL_GIZMO_SUBPOOL;
708 g->p.subpool = subpool;
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. */
720 pool_add_subpool (struct pool *pool, struct pool *subpool)
722 struct pool_gizmo *g;
724 assert (pool != NULL);
725 assert (subpool != NULL);
726 assert (subpool->parent == NULL);
728 g = pool_alloc (subpool, sizeof *g);
729 g->type = POOL_GIZMO_SUBPOOL;
730 g->p.subpool = subpool;
733 subpool->parent = pool;
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(). */
742 pool_fopen (struct pool *pool, const char *file_name, const char *mode)
746 assert (pool && file_name && mode);
747 f = fopen (file_name, mode);
749 pool_attach_file (pool, f);
754 /* Closes file FILE managed by POOL.
755 Returns 0 if successful, EOF if an I/O error occurred. */
757 pool_fclose (struct pool *pool, FILE *file)
759 assert (pool && file);
760 pool_detach_file (pool, file);
761 return fclose (file);
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(). */
769 pool_attach_file (struct pool *pool, FILE *file)
771 struct pool_gizmo *g = pool_alloc (pool, sizeof *g);
772 g->type = POOL_GIZMO_FILE;
777 /* Detaches FILE from POOL. */
779 pool_detach_file (struct pool *pool, FILE *file)
781 struct pool_gizmo *g;
783 for (g = pool->gizmos; g; g = g->next)
784 if (g->type == POOL_GIZMO_FILE && g->p.file == file)
786 delete_gizmo (pool, g);
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(). */
797 pool_create_temp_file (struct pool *pool)
799 FILE *file = create_temp_file ();
801 pool_attach_temp_file (pool, file);
805 /* Closes file FILE managed by POOL.
806 FILE must have been opened with create_temp_file(). */
808 pool_fclose_temp_file (struct pool *pool, FILE *file)
810 assert (pool && file);
811 pool_detach_temp_file (pool, file);
812 close_temp_file (file);
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(). */
820 pool_attach_temp_file (struct pool *pool, FILE *file)
822 struct pool_gizmo *g = pool_alloc (pool, sizeof *g);
823 g->type = POOL_GIZMO_TEMP_FILE;
828 /* Detaches FILE that was opened with create_temp_file() from POOL. */
830 pool_detach_temp_file (struct pool *pool, FILE *file)
832 struct pool_gizmo *g;
834 for (g = pool->gizmos; g; g = g->next)
835 if (g->type == POOL_GIZMO_TEMP_FILE && g->p.file == file)
837 delete_gizmo (pool, g);
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
848 pool_register (struct pool *pool, void (*free) (void *), void *p)
850 assert (pool && free && p);
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;
861 /* Unregisters previously registered P from POOL.
862 Returns true only if P was found to be registered in POOL. */
864 pool_unregister (struct pool *pool, void *p)
869 struct pool_gizmo *g;
871 for (g = pool->gizmos; g; g = g->next)
872 if (g->type == POOL_GIZMO_REGISTERED && g->p.registered.p == p)
874 delete_gizmo (pool, g);
882 /* Partial freeing. */
884 /* Notes the state of POOL into MARK so that it may be restored
885 by a call to pool_release(). */
887 pool_mark (struct pool *pool, struct pool_mark *mark)
889 assert (pool && mark);
891 mark->block = pool->blocks;
892 mark->ofs = pool->blocks->ofs;
894 mark->serial = serial;
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
902 pool_release (struct pool *pool, const struct pool_mark *mark)
904 assert (pool && mark);
907 struct pool_gizmo *cur, *next;
909 for (cur = pool->gizmos; cur && cur->serial >= mark->serial; cur = next)
925 struct pool_block *cur;
927 for (cur = pool->blocks; cur != mark->block; cur = cur->next)
929 cur->ofs = POOL_BLOCK_SIZE;
930 if ((char *) cur + POOL_BLOCK_SIZE == (char *) pool)
932 cur->ofs += POOL_SIZE;
933 if (pool->parent != NULL)
934 cur->ofs += POOL_GIZMO_SIZE;
937 pool->blocks = mark->block;
938 pool->blocks->ofs = mark->ofs;
942 /* Private functions. */
944 /* Adds GIZMO at the beginning of POOL's gizmo list. */
946 add_gizmo (struct pool *pool, struct pool_gizmo *gizmo)
948 assert (pool && gizmo);
951 gizmo->next = pool->gizmos;
954 pool->gizmos->prev = gizmo;
955 pool->gizmos = gizmo;
957 gizmo->serial = serial++;
959 check_gizmo (pool, gizmo);
962 /* Removes GIZMO from POOL's gizmo list. */
964 delete_gizmo (struct pool *pool, struct pool_gizmo *gizmo)
966 assert (pool && gizmo);
968 check_gizmo (pool, gizmo);
971 gizmo->prev->next = gizmo->next;
973 pool->gizmos = gizmo->next;
975 gizmo->next->prev = gizmo->prev;
978 /* Frees any of GIZMO's internal state.
979 GIZMO's data must not be referenced after calling this function. */
981 free_gizmo (struct pool_gizmo *gizmo)
983 assert (gizmo != NULL);
987 case POOL_GIZMO_MALLOC:
990 case POOL_GIZMO_FILE:
991 fclose (gizmo->p.file); /* Ignore errors. */
993 case POOL_GIZMO_TEMP_FILE:
994 close_temp_file (gizmo->p.file); /* Ignore errors. */
996 case POOL_GIZMO_SUBPOOL:
997 gizmo->p.subpool->parent = NULL;
998 pool_destroy (gizmo->p.subpool);
1000 case POOL_GIZMO_REGISTERED:
1001 gizmo->p.registered.free (gizmo->p.registered.p);
1008 /* Free all the gizmos in POOL. */
1010 free_all_gizmos (struct pool *pool)
1012 struct pool_gizmo *cur, *next;
1014 for (cur = pool->gizmos; cur; cur = next)
1019 pool->gizmos = NULL;
1023 check_gizmo (struct pool *p, struct pool_gizmo *g)
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));