2 tre-mem.c - TRE memory allocator
4 Copyright (c) 2001-2006 Ville Laurikari <vl@iki.fi>
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 This memory allocator is for allocating small memory blocks efficiently
24 in terms of memory overhead and execution speed. The allocated blocks
25 cannot be freed individually, only all at once. There can be multiple
35 /* Returns a new memory allocator or NULL if out of memory. */
37 tre_mem_new_impl(int provided, void *provided_block)
43 memset(mem, 0, sizeof(*mem));
46 mem = xcalloc(1, sizeof(*mem));
53 /* Frees the memory allocator and all memory allocated with it. */
55 tre_mem_destroy(tre_mem_t mem)
57 tre_list_t *tmp, *l = mem->blocks;
70 /* Allocates a block of `size' bytes from `mem'. Returns a pointer to the
71 allocated block or NULL if an underlying malloc() failed. */
73 tre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block,
74 int zero, size_t size)
80 DPRINT(("tre_mem_alloc: oops, called after failure?!\n"));
84 #ifdef MALLOC_DEBUGGING
90 DPRINT(("tre_mem_alloc: xmalloc forced failure\n"));
96 #endif /* MALLOC_DEBUGGING */
100 /* We need more memory than is available in the current block.
101 Allocate a new block. */
105 DPRINT(("tre_mem_alloc: using provided block\n"));
106 if (provided_block == NULL)
108 DPRINT(("tre_mem_alloc: provided block was NULL\n"));
112 mem->ptr = provided_block;
113 mem->n = TRE_MEM_BLOCK_SIZE;
118 if (size * 8 > TRE_MEM_BLOCK_SIZE)
119 block_size = size * 8;
121 block_size = TRE_MEM_BLOCK_SIZE;
122 DPRINT(("tre_mem_alloc: allocating new %d byte block\n",
124 l = xmalloc(sizeof(*l));
130 l->data = xmalloc(block_size);
138 if (mem->current != NULL)
139 mem->current->next = l;
140 if (mem->blocks == NULL)
148 /* Make sure the next pointer will be aligned. */
149 size += ALIGN(mem->ptr + size, long);
151 /* Allocate from current block. */
156 /* Set to zero if needed. */
158 memset(ptr, 0, size);