generated from 8dcc/c-template
-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
Hello,
First of all, thanks for this small and clean pool allocator — it has been very
useful in my project.
I am currently using libpool in a multithreaded environment and noticed that the
current implementation is not thread-safe (e.g. concurrent pool_alloc /
pool_free on the same Pool instance).
I would like to ask whether you would consider adding an optional thread-safe
mode in the future, for example by protecting the free list with a mutex inside
struct Pool.
One possible approach could be:
struct Pool {
void* free_chunk;
ArrayStart* array_starts;
size_t chunk_sz;
#ifdef LIBPOOL_THREAD_SAFE
pthread_mutex_t lock;
#endif
};
Pool* pool_new(size_t pool_sz, size_t chunk_sz) {
Pool* pool;
char* arr;
size_t i;
if (pool_sz == 0)
return NULL;
//.....
#ifdef LIBPOOL_THREAD_SAFE
pthread_mutex_init(&pool->lock, NULL);
#endif
return pool;
}
void* pool_alloc(Pool* pool) {
void* result;
if (pool == NULL)
return NULL;
VALGRIND_MAKE_MEM_DEFINED(pool, sizeof(Pool));
#ifdef LIBPOOL_THREAD_SAFE
pthread_mutex_lock(&pool->lock); //Added
#endif
if (pool->free_chunk == NULL) {
#ifdef LIBPOOL_THREAD_SAFE
pthread_mutex_unlock(&pool->lock);
#endif
return NULL;
}
VALGRIND_MAKE_MEM_DEFINED(pool->free_chunk, sizeof(void**));
result = pool->free_chunk;
pool->free_chunk = *(void**)pool->free_chunk;
#ifdef LIBPOOL_THREAD_SAFE
pthread_mutex_unlock(&pool->lock); //Added
#endif
VALGRIND_MEMPOOL_ALLOC(pool, result, pool->chunk_sz);
VALGRIND_MAKE_MEM_NOACCESS(pool->free_chunk, sizeof(void**));
VALGRIND_MAKE_MEM_NOACCESS(pool, sizeof(Pool));
return result;
}
void pool_free(Pool* pool, void* ptr) {
if (pool == NULL || ptr == NULL)
return;
VALGRIND_MAKE_MEM_DEFINED(pool, sizeof(Pool));
#ifdef LIBPOOL_THREAD_SAFE
pthread_mutex_lock(&pool->lock);
#endif
*(void**)ptr = pool->free_chunk;
pool->free_chunk = ptr;
#ifdef LIBPOOL_THREAD_SAFE
pthread_mutex_unlock(&pool->lock); //Added
#endif
VALGRIND_MAKE_MEM_NOACCESS(pool, sizeof(Pool));
VALGRIND_MEMPOOL_FREE(pool, ptr);
}The same mutex would also guard pool_expand and pool_destroy when enabled.
This would keep the current behavior unchanged for single-threaded users, while
making it easier and safer to use libpool in multithreaded programs.
Thanks again for the library!
Metadata
Metadata
Assignees
Labels
No labels