diff --git a/include/ucore/slot_allocator.h b/include/ucore/slot_allocator.h index b6d88da..55d4eb9 100644 --- a/include/ucore/slot_allocator.h +++ b/include/ucore/slot_allocator.h @@ -16,10 +16,11 @@ struct UCSlotArena { uint8_t *memory_start; size_t memory_len; size_t n_slots; + size_t used_slots; size_t slot_size; }; -/** +/** * Initialize a memory arena for dynamically allocating slots of memory. * Each allocation returns memory slots of the same size * Note: For max speed, align @memory and @slot_size to the size of a pointer @@ -53,26 +54,44 @@ static inline void uc_slot_arena_init(UCSlotArena *arena, void *memory, size_t m arena->slot_size = slot_size; } +/** + * Allocate a slot. + * + * @return pointer to a slot, NULL if all slots are already allocated + */ static inline void *uc_slot_alloc(UCSlotArena *arena) { UCSlot *slot = arena->free_list; if (slot != NULL) { arena->free_list = slot->next; + arena->used_slots++; } return slot; } - -static inline void uc_slot_free(UCSlotArena *arena, void *mem) +/** + * Free a slot. + * + * @param mem pointer to a slot that previously was allocated with uc_slot_alloc + */ +static inline void uc_slot_free(UCSlotArena *arena, void *memory) { - if (mem != NULL) { - assert((uint8_t *)mem >= arena->memory_start); - assert((uint8_t *)mem < arena->memory_start + arena->memory_len); - - UCSlot *slot = (UCSlot *)mem; + if (memory != NULL) { +#ifdef DEBUG + for (const UCSlot *slot = arena->free_list ; slot = slot->next) { + if (slot == mem) { + assert("Double free detected"); + } + } +#endif + assert((uint8_t *)memory >= arena->memory_start); + assert((uint8_t *)memory < arena->memory_start + arena->memory_len); + assert(arena->used_slots > 0); + UCSlot *slot = (UCSlot *)memory; slot->next = arena->free_list; arena->free_list = slot; + arena->used_slots--; } }