88 lines
2.4 KiB
C
88 lines
2.4 KiB
C
// memory_pool.c
|
|
#include "memory_pool.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
// Инициализировать пул памяти
|
|
struct memory_pool* memory_pool_init(size_t object_size) {
|
|
struct memory_pool* pool = 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 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
|
|
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;
|
|
free(obj);
|
|
obj = next;
|
|
}
|
|
|
|
pool->free_head = NULL;
|
|
pool->free_count = 0;
|
|
free(pool);
|
|
}
|