Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/memory_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
#define _MEMORY_POOL_H_

#include <stddef.h>
#include <pthread.h>

/* Magic numbers for double-free detection */
#define MEMORY_POOL_MAGIC_ALLOCATED 0xABCD1234U
#define MEMORY_POOL_MAGIC_FREE 0xDEADBEEFU

struct memory_pool_t
{
Expand All @@ -22,6 +27,7 @@ struct memory_pool_t
int node_count_allocated;
int node_count_free;
int node_count_total;
pthread_mutex_t mutex;
};
typedef struct memory_pool_t MEMORY_POOL;

Expand Down
58 changes: 57 additions & 1 deletion src/memory_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,45 @@
#include "memory_pool.h"
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

/* Align size to max_align_t for proper memory alignment */
static inline size_t align_size(size_t size)
{
size_t alignment = _Alignof(max_align_t);
return (size + alignment - 1) & ~(alignment - 1);
}

MEMORY_POOL *memory_pool_init(size_t node_size, size_t node_count_per_chunk, int chunk_count_limit)
{
MEMORY_POOL *p_pool;
size_t aligned_node_size;

if (node_size < sizeof(void *))
{
log_error("Error: node_size < sizeof(void *)");
return NULL;
}

/* Align node_size for proper memory alignment */
aligned_node_size = align_size(node_size);

p_pool = malloc(sizeof(MEMORY_POOL));
if (p_pool == NULL)
{
log_error("malloc(MEMORY_POOL) error: OOM");
return NULL;
}

p_pool->node_size = node_size;
/* Initialize mutex */
if (pthread_mutex_init(&p_pool->mutex, NULL) != 0)
{
log_error("pthread_mutex_init error");
free(p_pool);
return NULL;
}

p_pool->node_size = aligned_node_size;
p_pool->node_count_per_chunk = node_count_per_chunk;
p_pool->chunk_count_limit = chunk_count_limit;
p_pool->chunk_count = 0;
Expand All @@ -42,6 +62,7 @@ MEMORY_POOL *memory_pool_init(size_t node_size, size_t node_count_per_chunk, int
if (p_pool->p_chunks == NULL)
{
log_error("malloc(sizeof(void *) * %d) error: OOM", chunk_count_limit);
pthread_mutex_destroy(&p_pool->mutex);
free(p_pool);
return NULL;
}
Expand All @@ -60,6 +81,8 @@ void memory_pool_cleanup(MEMORY_POOL *p_pool)
return;
}

pthread_mutex_lock(&p_pool->mutex);

if (p_pool->node_count_allocated > 0)
{
log_error("Still have %d in-use nodes", p_pool->node_count_allocated);
Expand All @@ -72,6 +95,10 @@ void memory_pool_cleanup(MEMORY_POOL *p_pool)
}

free(p_pool->p_chunks);

pthread_mutex_unlock(&p_pool->mutex);
pthread_mutex_destroy(&p_pool->mutex);

free(p_pool);
}

Expand Down Expand Up @@ -124,9 +151,12 @@ void *memory_pool_alloc(MEMORY_POOL *p_pool)
return NULL;
}

pthread_mutex_lock(&p_pool->mutex);

if (p_pool->p_free == NULL && memory_pool_add_chunk(p_pool) == NULL)
{
log_error("Add chunk error");
pthread_mutex_unlock(&p_pool->mutex);
return NULL;
}

Expand All @@ -136,27 +166,53 @@ void *memory_pool_alloc(MEMORY_POOL *p_pool)
(p_pool->node_count_free)--;
(p_pool->node_count_allocated)++;

pthread_mutex_unlock(&p_pool->mutex);

return p_node;
}

void memory_pool_free(MEMORY_POOL *p_pool, void *p_node)
{
uint32_t *p_magic;

if (p_pool == NULL)
{
log_error("NULL pointer error");
return;
}

if (p_node == NULL)
{
log_error("Attempt to free NULL pointer");
return;
}

pthread_mutex_lock(&p_pool->mutex);

// For test and debug
#ifdef _DEBUG
memory_pool_check_node(p_pool, p_node);
#endif

/* Check for double-free using magic number at end of node */
p_magic = (uint32_t *)((char *)p_node + p_pool->node_size - sizeof(uint32_t));
if (*p_magic == MEMORY_POOL_MAGIC_FREE)
{
log_error("Double-free detected for node %p", p_node);
pthread_mutex_unlock(&p_pool->mutex);
return;
}

/* Mark node as free */
*p_magic = MEMORY_POOL_MAGIC_FREE;

memcpy(p_node, &(p_pool->p_free), sizeof(p_pool->p_free));
p_pool->p_free = p_node;

(p_pool->node_count_free)++;
(p_pool->node_count_allocated)--;

pthread_mutex_unlock(&p_pool->mutex);
}

int memory_pool_check_node(MEMORY_POOL *p_pool, void *p_node)
Expand Down