77 #define BLKID_SHIFT 16
78 #define BLKID_MASK ((1<<BLKID_SHIFT)-1)
84 char *caller_file,
int caller_line);
91 if ((elemsize %
sizeof(
void *)) != 0) {
92 size_t rounded = (elemsize +
sizeof(
void *) - 1) & ~(
sizeof(
void *)-1);
94 (
"List item size (%lu) not multiple of sizeof(void *), rounding to %lu\n",
95 (
unsigned long)elemsize,
96 (
unsigned long)rounded);
106 list->
blk_alloc = (1 << 18) / (MIN_ALLOC * elemsize);
108 E_ERROR(
"Element size * block size exceeds 256k, use malloc instead.\n");
116 listelem_add_block(list, __FILE__, __LINE__);
126 for (gn = list->
blocks; gn; gn = gnode_next(gn))
134 listelem_add_block(
listelem_alloc_t *list,
char *caller_file,
int caller_line)
147 if (blocksize * list->
elemsize > (1 << 18))
148 blocksize = (1 << 18) / list->
elemsize;
154 (
char **) __ckd_calloc__(blocksize, list->
elemsize,
155 caller_file, caller_line);
160 for (j = blocksize - 1; j > 0; --j) {
173 __listelem_malloc__(
listelem_alloc_t *list,
char *caller_file,
int caller_line)
179 listelem_add_block(list, caller_file, caller_line);
191 int caller_line, int32 *out_id)
197 listelem_add_block(list, caller_file, caller_line);
205 int32 blksize, blkidx, ptridx;
212 for (gn = list->
blocks; gn; gn = gnode_next(gn)) {
214 blksize = gnode_int32(gn2) * list->
elemsize /
sizeof(*block);
215 if (ptr >= block && ptr < block + blksize)
217 gn2 = gnode_next(gn2);
221 E_ERROR(
"Failed to find block index for pointer %p!\n", ptr);
223 ptridx = (ptr - block) / (list->
elemsize /
sizeof(*block));
224 E_DEBUG(4,(
"ptr %p block %p blkidx %d ptridx %d\n",
225 ptr, block, list->n_blocks - blkidx - 1, ptridx));
226 *out_id = ((list->n_blocks - blkidx - 1) << BLKID_SHIFT) | ptridx;
235 int32 blkidx, ptridx, i;
238 blkidx = (
id >> BLKID_SHIFT) & BLKID_MASK;
239 ptridx =
id & BLKID_MASK;
242 blkidx = list->n_blocks - blkidx;
243 for (gn = list->
blocks; gn; gn = gnode_next(gn)) {
248 E_ERROR(
"Failed to find block index %d\n", blkidx);
253 + ptridx * (list->
elemsize /
sizeof(
void *)));
258 char *caller_file,
int caller_line)
265 cpp = (
char **) elem;
279 E_INFO(
"Linklist stats:\n");
280 for (n = 0, cpp = list->
freelist; cpp;
281 cpp = (
char **) (*cpp), n++);
283 (
"elemsize %lu, #alloc %lu, #freed %lu, #freelist %lu\n",
285 (
unsigned long)list->n_alloc,
286 (
unsigned long)list->n_freed,
288 E_INFO(
"Allocated blocks:\n");
290 for (gn = list->
blocks; gn; gn = gnode_next(gn)) {
292 gn2 = gnode_next(gn2);
#define ckd_calloc(n, sz)
Macros to simplify the use of above functions.
SPHINXBASE_EXPORT glist_t glist_add_int32(glist_t g, int32 val)
Create and prepend a new list node containing an integer.
#define E_DEBUG(level, x)
Print debugging information to standard error stream.
#define E_INFO
Print logging information to standard error stream.
Sphinx's memory allocation/deallocation routines.
A node in a generic list.
SPHINXBASE_EXPORT void ckd_free(void *ptr)
Test and free a 1-D array.
SPHINXBASE_EXPORT glist_t glist_add_ptr(glist_t g, void *ptr)
Create and prepend a new list node, with the given user-defined data, at the HEAD of the given generi...
#define E_WARN
Print warning information to standard error stream.
glist_t blocks
Linked list of blocks allocated.
Fast linked list allocator.
SPHINXBASE_EXPORT void glist_free(glist_t g)
Free the given generic list; user-defined data contained within is not automatically freed...
SPHINXBASE_EXPORT void * listelem_get_item(listelem_alloc_t *le, int32 id)
Retrieve a list element by its identifier.
#define gnode_ptr(g)
Head of a list of gnodes.
Fast memory allocator for uniformly sized objects.
Implementation of logging routines.
char ** freelist
ptr to first element in freelist
Generic linked-lists maintenance.
#define E_ERROR
Print error message to standard error stream.
size_t blk_alloc
Number of alloc operations before increasing blocksize.
SPHINXBASE_EXPORT listelem_alloc_t * listelem_alloc_init(size_t elemsize)
Initialize and return a list element allocator.
glist_t blocksize
Number of elements in each block.
size_t elemsize
Number of (char *) in element.
SPHINXBASE_EXPORT void listelem_stats(listelem_alloc_t *le)
Print number of allocation, numer of free operation stats.
SPHINXBASE_EXPORT void __listelem_free__(listelem_alloc_t *le, void *elem, char *file, int line)
Free list element of given size.
SPHINXBASE_EXPORT void listelem_alloc_free(listelem_alloc_t *le)
Finalize and release all memory associated with a list element allocator.