/* fastheap.h */ /* Copyright 1997 by Eberhard Mattes Donated to the public domain. No warranty. 1997-07-22 Initial version */ /* This code implements a fast heap for memory allocation. There are several restrictions: Objects cannot be deallocated (however, the entire fast heap can be reset to the empty state), no alignment is guaranteed, there might be quite a lot of overhead for allocating big objects (fragmentation), a fast heap never shrinks. On the other hand, it probably cannot be done faster. A fast heap is implemented as a single linked list of chunks. Allocation is always done from the `current chunk'; if there's not enough space left in that chunk, we move on to the next one, creating one if necessary. The fast heap implementation uses xmalloc() for obtaining memory; therefore, the process will be terminated when we run out of memory. */ /* Each chunk starts with an instance of this structure. The bytes following this structure are available for allocation. */ struct fastheap_header { struct fastheap_header *next; /* Pointer to next chunk */ size_t size; /* Size excluding header */ }; /* This structure controls one fast heap. */ typedef struct { struct fastheap_header *first; /* The head of the linked list */ struct fastheap_header *cur; /* Pointer to current chunk, or NULL */ struct fastheap_header **add; /* Add new chunk here */ size_t chunk_size; /* Minimum chunk size, including header */ size_t cur_avail; /* Amount of free space in current chunk */ char *cur_ptr; /* Pointer to free space in current chunk */ } fastheap; void fastheap_init (fastheap *, size_t); void fastheap_add_static (fastheap *, void *, size_t); void fastheap_reset (fastheap *); void *fastheap_memdup (fastheap *, const void *, size_t); char *fastheap_strndup (fastheap *, const char *, size_t); void *fastheap_alloc1 (fastheap *, size_t); void fastheap_alloc_assert (fastheap *); /* fastheap_alloc() never returns a NULL pointer (this is also true for SZ==0). Note: We waste one character per chunk in order to make the case of SZ==0 faster (note that we use "<" instead of "<=" for comparing SZ to CUR_AVAIL. */ #define fastheap_alloc(hp,sz) ( FASTHEAP_ALLOC_ASSERT (hp), \ ((size_t)(sz) < (hp)->cur_avail \ ? (hp)->cur_avail -= (sz), (hp)->cur_ptr += (sz), (hp)->cur_ptr - (sz) \ : fastheap_alloc1 ((hp), (sz)))) #ifdef NDEBUG #define FASTHEAP_ALLOC_ASSERT(hp) ((void)0) #else #define FASTHEAP_ALLOC_ASSERT(hp) fastheap_alloc_assert(hp) #endif