/* * free a malloc_elem block by adding it to the free list. If the * blocks either immediately before or immediately after newly freed block * are also free, the blocks are merged together. */ int malloc_elem_free(struct malloc_elem *elem) { if (!malloc_elem_cookies_ok(elem) || elem->state != ELEM_BUSY) return -1; rte_spinlock_lock(&(elem->heap->lock)); struct malloc_elem *next = RTE_PTR_ADD(elem, elem->size); if (next->state == ELEM_FREE){ /* remove from free list, join to this one */ elem_free_list_remove(next); join_elem(elem, next); } /* check if previous element is free, if so join with it and return, * need to re-insert in free list, as that element's size is changing */ if (elem->prev != NULL && elem->prev->state == ELEM_FREE) { elem_free_list_remove(elem->prev); join_elem(elem->prev, elem); malloc_elem_free_list_insert(elem->prev); } /* otherwise add ourselves to the free list */ else { malloc_elem_free_list_insert(elem); elem->pad = 0; } /* decrease heap's count of allocated elements */ elem->heap->alloc_count--; rte_spinlock_unlock(&(elem->heap->lock)); return 0; }
int rte_malloc_validate(const void *ptr, size_t *size) { const struct malloc_elem *elem = malloc_elem_from_data(ptr); if (!malloc_elem_cookies_ok(elem)) return -1; if (size != NULL) *size = elem->size - elem->pad - MALLOC_ELEM_OVERHEAD; return 0; }