// memory_pool.c #include #include #include #include "memory_pool.h" #include "mem.h" // Инициализировать пул памяти struct memory_pool* memory_pool_init(size_t object_size) { struct memory_pool* pool = u_calloc(1, sizeof(struct memory_pool)); if (!pool) { return NULL; } pool->free_head = NULL; pool->object_size = object_size; pool->free_count = 0; pool->allocations = 0; pool->reuse_count = 0; return pool; } // Выделить объект из пула или из malloc void* memory_pool_alloc(struct memory_pool* pool) { if (!pool) { return NULL; } if (pool->free_head) { void* obj = pool->free_head; pool->free_head = *(void**)obj; // Извлекаем next из начала блока pool->free_count--; pool->reuse_count++; memset(obj, 0, pool->object_size); // Опционально: очищаем память для безопасности return obj; } pool->allocations++; return u_calloc(1, pool->object_size); // Используем calloc для инициализации нулями } // Освободить объект в пул или в free void memory_pool_free(struct memory_pool* pool, void* obj) { if (!pool || !obj) { return; } // Если пул не заполнен, сохранить объект для повторного использования if (pool->free_count < MEMORY_POOL_MAX_FREE) { *(void**)obj = pool->free_head; // Сохраняем next в начало блока pool->free_head = obj; pool->free_count++; return; } // Иначе освободить через free u_free(obj); } // Получить статистику пула void memory_pool_get_stats(struct memory_pool* pool, size_t* allocations, size_t* reuse_count) { if (!pool) { return; } if (allocations) { *allocations = pool->allocations; } if (reuse_count) { *reuse_count = pool->reuse_count; } } // Очистить пул памяти void memory_pool_destroy(struct memory_pool* pool) { if (!pool) { return; } // Освободить все объекты в пуле void* obj = pool->free_head; while (obj) { void* next = *(void**)obj; u_free(obj); obj = next; } pool->free_head = NULL; pool->free_count = 0; u_free(pool); }