Fix distribution.
[mLib] / sub.h
1 /* -*-c-*-
2 *
3 * $Id: sub.h,v 1.7 2003/10/12 14:44:46 mdw Exp $
4 *
5 * Allocation of known-size blocks
6 *
7 * (c) 1998 Straylight/Edgeware
8 */
9
10 /*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of the mLib utilities library.
13 *
14 * mLib is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * mLib is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with mLib; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
28 */
29
30 /*----- Revision history --------------------------------------------------*
31 *
32 * $Log: sub.h,v $
33 * Revision 1.7 2003/10/12 14:44:46 mdw
34 * Various fixes.
35 *
36 * Revision 1.6 2000/06/17 10:35:51 mdw
37 * Major overhaul for arena support.
38 *
39 * Revision 1.5 1999/12/10 23:42:04 mdw
40 * Change header file guard names.
41 *
42 * Revision 1.4 1999/05/13 22:48:55 mdw
43 * Change `-ise' to `-ize' throughout.
44 *
45 * Revision 1.3 1999/05/06 19:51:35 mdw
46 * Reformatted the LGPL notice a little bit.
47 *
48 * Revision 1.2 1999/05/05 18:50:31 mdw
49 * Change licensing conditions to LGPL.
50 *
51 * Revision 1.1.1.1 1998/06/17 23:44:42 mdw
52 * Initial version of mLib
53 *
54 */
55
56 #ifndef MLIB_SUB_H
57 #define MLIB_SUB_H
58
59 #ifdef __cplusplus
60 extern "C" {
61 #endif
62
63 /*----- Required header files ---------------------------------------------*/
64
65 #include <stdlib.h>
66
67 #ifndef MLIB_ALIGN_H
68 # include "align.h"
69 #endif
70
71 #ifndef MLIB_ARENA_H
72 # include "arena.h"
73 #endif
74
75 /*----- Configuration and tuning ------------------------------------------*/
76
77 /* --- The largest block I'll handle here --- *
78 *
79 * Anything larger will be handed on to the underlying @alloc@.
80 */
81
82 #define SUB_MAXBIN 256
83
84 /* --- Preferred chunk size --- *
85 *
86 * When a bin is empty, I'll allocate a large chunk of approximately this
87 * size and divvy it up into small bin-sized blocks.
88 */
89
90 #define SUB_CHUNK 4096
91
92 /*----- Other useful macros -----------------------------------------------*/
93
94 /* --- The granularity of bin buffers --- *
95 *
96 * All blocks allocated by the binner are a multiple of this size.
97 */
98
99 #define SUB_GRANULE sizeof(union align)
100
101 /* --- Finding the right bin for a given size --- *
102 *
103 * This chooses the correct bin for an allocation. Input is the size of
104 * block wanted; result is the bin index.
105 */
106
107 #define SUB_BIN(x) (((x) + SUB_GRANULE - 1) / SUB_GRANULE)
108
109 /* --- Convert a bin back to the block size --- *
110 *
111 * This gives the size of block contained in a given bin.
112 */
113
114 #define SUB_BINSZ(x) ((x) * SUB_GRANULE)
115
116 /* --- Number of bins required --- */
117
118 #define SUB_BINS (SUB_MAXBIN / SUB_GRANULE + 1)
119
120 /*----- Data structures ---------------------------------------------------*/
121
122 typedef struct subarena {
123 arena *a;
124 void *bin[SUB_BINS];
125 } subarena;
126
127 /*----- Global variables --------------------------------------------------*/
128
129 extern subarena sub_global;
130
131 /*----- Functions provided ------------------------------------------------*/
132
133 /* --- @subarena_create@ --- *
134 *
135 * Arguments: @subarena *s@ = pointer to arena to initialize
136 * @arena *a@ = pointer to underlying arena block
137 *
138 * Returns: ---
139 *
140 * Use: Initialize a suballocation arena based on an underlying large
141 * blocks arena.
142 */
143
144 extern void subarena_create(subarena */*s*/, arena */*a*/);
145
146 /* --- @subarena_destroy@ --- *
147 *
148 * Arguments: @subarena *s@ = pointer to arena to destroy
149 *
150 * Returns: ---
151 *
152 * Use: Destroys a suballocation arena, freeing all of the memory it
153 * contains back to the underlying large blocks arena.
154 */
155
156 extern void subarena_destroy(subarena */*s*/);
157
158 /* --- @subarena_alloc@ --- *
159 *
160 * Arguments: @subarena *s@ = pointer to arena
161 * @size_t s@ = size of chunk wanted
162 *
163 * Returns: Pointer to a block at least as large as the one wanted.
164 *
165 * Use: Allocates a small block of memory from the given pool. The
166 * exception @EXC_NOMEM@ is raised if the underlying arena is
167 * full.
168 */
169
170 extern void *subarena_alloc(subarena */*s*/, size_t /*sz*/);
171
172 /* --- @subarena_free@ --- *
173 *
174 * Arguments: @subarena *s@ = pointer to arena
175 * @void *p@ = address of block to free
176 * @size_t s@ = size of block
177 *
178 * Returns: ---
179 *
180 * Use: Frees a block allocated by @subarena_alloc@.
181 */
182
183 extern void subarena_free(subarena */*s*/, void */*p*/, size_t /*sz*/);
184
185 /* --- @A_CREATE@ --- *
186 *
187 * Arguments: @subarena *s@ = pointer to arena
188 * @type@ = type of object required; must be passable to
189 * @sizeof@
190 *
191 * Returns: Pointer to a block sufficiently big to hold an object of the
192 * named type.
193 *
194 * Use: Allocates a block of the required type.
195 */
196
197 #define A_CREATE(a, type) subarena_alloc((a), sizeof(type))
198
199 /* --- @A_DESTROY@ --- *
200 *
201 * Arguments: @subarena *s@ = pointer to arena
202 * @void *p@ = pointer to an object
203 *
204 * Returns: ---
205 *
206 * Use: Frees the thing pointed to by @p@.
207 */
208
209 #define A_DESTROY(a, p) subarena_free((a), (p), sizeof(*p))
210
211 /*----- Shortcuts for the global pool -------------------------------------*/
212
213 /* --- @sub_alloc@ --- *
214 *
215 * Arguments: @size_t s@ = size of chunk wanted
216 *
217 * Returns: Pointer to a block at least as large as the one wanted.
218 *
219 * Use: Allocates a small block of memory from the @sub_global@ pool.
220 */
221
222 extern void *sub_alloc(size_t /*sz*/);
223 #define sub_alloc(sz) subarena_alloc(&sub_global, (sz))
224
225 /* --- @sub_free@ --- *
226 *
227 * Arguments: @void *p@ = address of block to free
228 * @size_t s@ = size of block
229 *
230 * Returns: ---
231 *
232 * Use: Frees a block allocated by @sub_alloc@.
233 */
234
235 extern void sub_free(void */*p*/, size_t /*sz*/);
236 #define sub_free(p, sz) subarena_free(&sub_global, (p), (sz))
237
238 /* --- @CREATE@ --- *
239 *
240 * Arguments: @type@ = type of object required; must be passable to
241 * @sizeof@
242 *
243 * Returns: Pointer to a block sufficiently big to hold an object of the
244 * named type.
245 *
246 * Use: Allocates a block of the required type.
247 */
248
249 #define CREATE(type) sub_alloc(sizeof(type))
250
251 /* --- @DESTROY@ --- *
252 *
253 * Arguments: @void *p@ = pointer to an object
254 *
255 * Returns: ---
256 *
257 * Use: Frees the thing pointed to by @p@.
258 */
259
260 #define DESTROY(p) sub_free(p, sizeof(*p))
261
262 /* --- @sub_init@ --- *
263 *
264 * Arguments: ---
265 *
266 * Returns: ---
267 *
268 * Use: Initializes the magic allocator. This is no longer
269 * necessary.
270 */
271
272 extern void sub_init(void);
273
274 /*----- That's all, folks -------------------------------------------------*/
275
276 #ifdef __cplusplus
277 }
278 #endif
279
280 #endif