add a PLANNED_TEST() macro to test.h
[nobug.git] / src / mpool.h
blobe8f38e4df0b69c1d6d92b1167e0a7cfa8345314c
1 /*
2 mpool.h - memory pool for constant sized objects
4 Copyright (C) Lumiera.org
5 2009, Christian Thaeter <ct@pipapo.org>
7 This is a crippled version for nobug, the original version is maintained in lumiera
8 (nobug debugging itself is left out here)
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2 of the
13 License, or (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include <stdint.h>
26 #include "llist.h"
29 //mpool Memory Pools
30 //mpool ------------
31 //mpool
32 //mpool This memory pools are implemented as clusters of fixed sized elements. New clusters
33 //mpool are allocated on demand or manually preallocated with a `reserve()` operation.
34 //mpool Some efforts are taken to ensure (cache) locality of the provided memory.
35 //mpool All functions are reentrant but not threadsafe, if this is desired it is advised to
36 //mpool care for proper locking elsewhere.
37 //mpool
42 //index.mpool_destroy_fn xref:mpool_destroy_fn[mpool_destroy_fn]:: function prototype for destroying elements
43 //mpool [[mpool_destroy_fn]]
44 //mpool .mpool_destroy_fn
45 //mpool When a memory pool gets destroyed it can call a destructor for any element which is still in the pool.
46 //mpool This destructor is optional.
47 //mpool
48 //mpool typedef void (*mpool_destroy_fn)(void* self)
49 //mpool
50 //mpool `self`::
51 //mpool element to be destroyed
52 //mpool
54 typedef void (*mpool_destroy_fn)(void* self);
58 //index.struct_mpool xref:struct_mpool[mpool (struct)]:: the memory pool management structure
59 //mpool [[struct_mpool]]
60 //mpool .mpool
61 //mpool typedef struct mpool_struct mpool
62 //mpool typedef mpool* MPool
63 //mpool typedef const mpool* const_MPool
64 //mpool
65 //mpool This structure should be considered opaque.
67 typedef struct mpool_struct mpool;
68 typedef mpool* MPool;
69 typedef const mpool* const_MPool;
71 struct mpool_struct
73 llist freelist;
74 llist clusters;
75 size_t elem_size;
76 unsigned elements_per_cluster;
77 uintptr_t cluster_size;
78 unsigned elements_free; /* a counter of free elements is the price we pay to support a reserve() operation */
79 void* locality;
80 mpool_destroy_fn destroy;
85 //index.mpool_init xref:mpool_init[mpool_init()]:: initialize a new memory pool
86 //mpool [[mpool_init]]
87 //mpool .mpool_init
88 //mpool Initialize a memory pool, memory pools must be initialized before being used. One can supply
89 //mpool an optional destructor function for elements, this will be used to destroy elements which are still
90 //mpool in the pool when it gets destroyed itself. The destructor is _NOT_ called when elemented are freed.
91 //mpool
92 //mpool MPool mpool_init (MPool self, size_t elem_size, unsigned elements_per_cluster, mpool_move_fn mv, mpool_destroy_fn dtor)
93 //mpool
94 //mpool `self`::
95 //mpool pointer to the memory pool structure to be initialized
96 //mpool `elem_size`::
97 //mpool size for a single element
98 //mpool `elements_per_cluster`::
99 //mpool how many elements to put into a cluster
100 //mpool `dtor`::
101 //mpool pointer to an optional destructor function or NULL
102 //mpool return::
103 //mpool self
104 //mpool
106 MPool
107 mpool_init (MPool self, size_t elem_size, unsigned elements_per_cluster, mpool_destroy_fn dtor);
111 //index.mpool_destroy xref:mpool_destroy[mpool_destroy()]:: destroy a memory pool
112 //mpool [[mpool_destroy]]
113 //mpool .mpool_destroy
114 //mpool A memory pool is not used anymore it should be destroyed. This frees all memory allocated with it.
115 //mpool When a destructor was provided at construction time, then this destructor is used on all non free elements
116 //mpool before before the clusters are freed. If no destructor was given then the clusters are just freed.
117 //mpool The destroyed memory pool behaves as if it was freshly initialized and can be used again, this is some kindof
118 //mpool exceptional behaviour.
119 //mpool
120 //mpool MPool mpool_destroy (MPool self)
121 //mpool
122 //mpool `self`::
123 //mpool pointer to an initialized memory pool to be destroyed.
124 //mpool return::
125 //mpool self
126 //mpool
127 //mpool
129 MPool
130 mpool_destroy (MPool self);
134 //index.mpool_available xref:mpool_available[mpool_available()]:: query number of free elements
135 //mpool [[mpool_available]]
136 //mpool .mpool_available
137 //mpool One can check how much elements are available without a new cluster allocation in a memory pool.
138 //mpool
139 //mpool unsigned mpool_available (MPool self)
140 //mpool
141 //mpool `self`::
142 //mpool pointer to the memory pool to be queried
143 //mpool return::
144 //mpool number of available elements
145 //mpool
147 static inline unsigned
148 mpool_available (MPool self)
150 return self->elements_free;
155 //index.mpool_reserve xref:mpool_reserve[mpool_reserve()]:: preallocate elements
156 //mpool [[mpool_reserve]]
157 //mpool .mpool_reserve
158 //mpool Resize the pool that at least nelements become available without cluster reallocations
159 //mpool
160 //mpool unsigned mpool_reserve (MPool self, unsigned nelements)
161 //mpool
162 //mpool `self`::
163 //mpool pointer to the memory pool
164 //mpool `nelements`::
165 //mpool minimum number of elements to preallocate
166 //mpool return::
167 //mpool self on success or NULL on error
168 //mpool
170 MPool
171 mpool_reserve (MPool self, unsigned nelements);
175 //index.mpool_alloc xref:mpool_alloc[mpool_alloc()]:: allocate one element
176 //mpool [[mpool_alloc]]
177 //mpool .mpool_alloc
178 //mpool Allocates on element from a mpool. To improve cache locality allocations
179 //mpool are grouped close together to recent allocations.
180 //mpool
181 //mpool void* mpool_alloc (MPool self)
182 //mpool
183 //mpool `self`::
184 //mpool pointer to the memory pool
185 //mpool return::
186 //mpool pointer to the allocated memory on success or NULL on error
187 //mpool will never fail when enough space was preallocated
188 //mpool
190 void*
191 mpool_alloc (MPool self);
195 //index.mpool_alloc_near xref:mpool_alloc_near[mpool_alloc_near()]:: allocate one element, w/ locality
196 //mpool [[mpool_alloc_near]]
197 //mpool .mpool_alloc_near
198 //mpool Allocates on element from a mpool. To improve cache locality the allocation
199 //mpool tries to get an element close to another.
200 //mpool
201 //mpool void* mpool_alloc_near (MPool self, void* near)
202 //mpool
203 //mpool `self`::
204 //mpool pointer to the memory pool
205 //mpool `near`::
206 //mpool reference to another element which should be close to the returned element (hint only)
207 //mpool return::
208 //mpool pointer to the allocated memory on success or NULL on error
209 //mpool will never fail when enough space was preallocated
210 //mpool
212 void*
213 mpool_alloc_near (MPool self, void* near);
217 //index.mpool_free xref:mpool_free[mpool_free()]:: free one element
218 //mpool [[mpool_free]]
219 //mpool .mpool_free
220 //mpool Frees the given element and puts it back into the pool for furhter allocations.
221 //mpool
222 //mpool void mpool_free (MPool self, void* element)
223 //mpool
224 //mpool `self`::
225 //mpool pointer to the memory pool
226 //mpool `element`::
227 //mpool element to be freed
228 //mpool
230 void
231 mpool_free (MPool self, void* element);
235 void
236 nobug_mpool_dump (const_MPool self,
237 const int depth,
238 const char* file,
239 const int line,
240 const char* func);
243 // Local Variables:
244 // mode: C
245 // c-file-style: "gnu"
246 // indent-tabs-mode: nil
247 // End: