/* %z */ static int print_block_head (FILE * stream, const struct printf_info *info, const void *const *args) { const struct buffer_head * bh; char * buffer; int len; bh = *((const struct buffer_head **)(args[0])); len = asprintf (&buffer, "level=%d, nr_items=%d, free_space=%d rdkey", B_LEVEL (bh), B_NR_ITEMS (bh), node_free_space (bh)); FPRINTF; }
apr_status_t heap_gc(heap_t *hp, term_t *roots[], int root_sizes[], int nroots) { apr_memnode_t *saved_active; apr_memnode_t *gc_node, *copy_node; int node_size; int i, j; if (hp->gc_last == NULL) // gc never run gc_node = hp->active; else gc_node = hp->gc_last->next; node_size = node_alloc_size(gc_node); // if gc_last node has enough space then use it for // live term copies, otherwise, create a new node // NB: gc_last may point to gc_node if (hp->gc_last != NULL && hp->gc_last != gc_node && node_free_space(hp->gc_last) >= node_size) copy_node = hp->gc_last; else copy_node = apr_allocator_alloc(hp->allocator, node_size); // temporarily make copy_node active; restore later saved_active = hp->active; hp->active = copy_node; hp->hend = heap_htop(hp); // save gc_node reference for seek_alive; // non-NULL gc_spot means gc in progress hp->gc_spot = gc_node; for (i = 0; i < nroots; i++) for (j = 0; j < root_sizes[i]; j++) seek_live(&roots[i][j], saved_active, hp); assert(hp->active == copy_node); // no overflow hp->gc_spot = NULL; // restore active node if (saved_active != gc_node) hp->active = saved_active; // insert copy_node into the ring: // if gc_node is the last node left // if copy_node is non-empty and was just created; // free copy_node if it was just created // and not put on the list if (gc_node->next == gc_node || (node_alloc_size(copy_node) > 0 && copy_node != hp->gc_last)) { list_insert(copy_node, gc_node); hp->gc_last = copy_node; } else if (copy_node != hp->gc_last) { if (hp->active == copy_node) hp->active = gc_node->next; apr_allocator_free(hp->allocator, copy_node); } hp->alloc_size -= node_alloc_size(gc_node); // reclaim memory list_remove(gc_node); gc_node->next = NULL; apr_allocator_free(hp->allocator, gc_node); // after gc is run, anticipated need is zero hp->hend = heap_htop(hp); return APR_SUCCESS; }