97 |
|
|
98 |
/* This should be the alignment size used by malloc(). The size of |
/* This should be the alignment size used by malloc(). The size of |
99 |
the union above is correct, if not optimal, in all known cases. */ |
the union above is correct, if not optimal, in all known cases. */ |
|
#if defined (i386) || defined (__i386__) |
|
|
#define ALIGN_SIZE 4 /* Save some extra memory. */ |
|
|
#else |
|
100 |
#define ALIGN_SIZE sizeof (union align) |
#define ALIGN_SIZE sizeof (union align) |
|
#endif |
|
101 |
|
|
102 |
/* DISCRETE_BLOCKS may be declared as nonzero to prevent |
/* DISCRETE_BLOCKS may be declared as nonzero to prevent |
103 |
suballocation of blocks. This is useful under memory |
suballocation of blocks. This is useful under memory |
241 |
/* Suballocation routines. */ |
/* Suballocation routines. */ |
242 |
|
|
243 |
/* Allocates a memory region AMT bytes in size from POOL and returns a |
/* Allocates a memory region AMT bytes in size from POOL and returns a |
244 |
pointer to the region's start. */ |
pointer to the region's start. |
245 |
|
The region is properly aligned for storing any object. */ |
246 |
void * |
void * |
247 |
pool_alloc (struct pool *pool, size_t amt) |
pool_alloc (struct pool *pool, size_t amt) |
248 |
{ |
{ |
249 |
assert (pool != NULL); |
assert (pool != NULL); |
250 |
|
|
251 |
|
if (amt == 0) |
252 |
|
return NULL; |
253 |
|
|
254 |
#ifndef DISCRETE_BLOCKS |
#ifndef DISCRETE_BLOCKS |
255 |
if (amt <= MAX_SUBALLOC) |
if (amt <= MAX_SUBALLOC) |
295 |
return pool_malloc (pool, amt); |
return pool_malloc (pool, amt); |
296 |
} |
} |
297 |
|
|
298 |
|
/* Allocates a memory region AMT bytes in size from POOL and |
299 |
|
returns a pointer to the region's start. The region is not |
300 |
|
necessarily aligned, so it is most suitable for storing |
301 |
|
strings. */ |
302 |
|
void * |
303 |
|
pool_alloc_unaligned (struct pool *pool, size_t amt) |
304 |
|
{ |
305 |
|
assert (pool != NULL); |
306 |
|
|
307 |
|
#ifndef DISCRETE_BLOCKS |
308 |
|
/* Strings need not be aligned on any boundary, but some |
309 |
|
operations may be more efficient when they are. However, |
310 |
|
that's only going to help with reasonably long strings. */ |
311 |
|
if (amt < ALIGN_SIZE) |
312 |
|
{ |
313 |
|
if (amt == 0) |
314 |
|
return NULL; |
315 |
|
else |
316 |
|
{ |
317 |
|
struct pool_block *const b = pool->blocks; |
318 |
|
|
319 |
|
if (b->ofs + amt <= BLOCK_SIZE) |
320 |
|
{ |
321 |
|
void *p = ((char *) b) + b->ofs; |
322 |
|
b->ofs += amt; |
323 |
|
return p; |
324 |
|
} |
325 |
|
} |
326 |
|
} |
327 |
|
#endif |
328 |
|
|
329 |
|
return pool_alloc (pool, amt); |
330 |
|
} |
331 |
|
|
332 |
/* Allocates a memory region N * S bytes in size from POOL and |
/* Allocates a memory region N * S bytes in size from POOL and |
333 |
returns a pointer to the region's start. |
returns a pointer to the region's start. |
334 |
N must be nonnegative, S must be positive. |
N must be nonnegative, S must be positive. |
352 |
return block; |
return block; |
353 |
} |
} |
354 |
|
|
355 |
/* Duplicates STRING, which has LENGTH characters, within POOL, |
/* Allocates SIZE bytes of unaligned data in POOL, copies BUFFER |
356 |
and returns a pointer to the duplicate. LENGTH should not |
into it, and returns the new copy. */ |
357 |
include the null terminator, which is always added to the |
void * |
358 |
duplicate. For use only with strings, because the returned |
pool_clone_unaligned (struct pool *pool, const void *buffer, size_t size) |
|
pointere may not be aligned properly for other types. */ |
|
|
char * |
|
|
pool_strndup (struct pool *pool, const char *string, size_t length) |
|
359 |
{ |
{ |
360 |
size_t size; |
void *block = pool_alloc_unaligned (pool, size); |
361 |
char *copy; |
memcpy (block, buffer, size); |
362 |
|
return block; |
|
assert (pool && string); |
|
|
size = length + 1; |
|
|
|
|
|
/* Note that strings need not be aligned on any boundary. */ |
|
|
#ifndef DISCRETE_BLOCKS |
|
|
{ |
|
|
struct pool_block *const b = pool->blocks; |
|
|
|
|
|
if (b->ofs + size <= BLOCK_SIZE) |
|
|
{ |
|
|
copy = ((char *) b) + b->ofs; |
|
|
b->ofs += size; |
|
|
} |
|
|
else |
|
|
copy = pool_alloc (pool, size); |
|
|
} |
|
|
#else |
|
|
copy = pool_alloc (pool, size); |
|
|
#endif |
|
|
|
|
|
memcpy (copy, string, length); |
|
|
copy[length] = '\0'; |
|
|
return copy; |
|
363 |
} |
} |
364 |
|
|
365 |
/* Duplicates null-terminated STRING, within POOL, and returns a |
/* Duplicates null-terminated STRING, within POOL, and returns a |
369 |
char * |
char * |
370 |
pool_strdup (struct pool *pool, const char *string) |
pool_strdup (struct pool *pool, const char *string) |
371 |
{ |
{ |
372 |
return pool_strndup (pool, string, strlen (string)); |
return pool_clone_unaligned (pool, string, strlen (string) + 1); |
373 |
} |
} |
374 |
|
|
375 |
/* Standard allocation routines. */ |
/* Standard allocation routines. */ |