rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

commit a50e608d561b31075467715def89992b278da7ee
parent 7224db2bc059ef958349eae79912bc9f229116e0
Author: vaplv <vaplv@free.fr>
Date:   Mon,  2 Mar 2015 23:37:59 +0100

Make the proxy allocator thread safe

Diffstat:
Msrc/mem_allocator.c | 44++++++++++++++++++++++++++++++++++----------
Msrc/mem_allocator.h | 2+-
2 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/src/mem_allocator.c b/src/mem_allocator.c @@ -14,8 +14,9 @@ * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ #define _POSIX_C_SOURCE 200112L /* snprintf support */ -#include "mem_allocator.h" #include "math.h" +#include "mem_allocator.h" +#include "mutex.h" #include <errno.h> #include <malloc.h> @@ -377,6 +378,7 @@ default_dump struct proxy_data { struct mem_allocator* allocator; + struct mutex* mutex; struct mem_node* node_list; }; @@ -421,14 +423,17 @@ proxy_alloc_aligned mem = (char*)((uintptr_t)node + (uintptr_t)node_header_size); mem[-1] = (char)(align_adjusted & 0xFF); mem[-2] = (char)((align_adjusted >> 8) & 0xFF); - node->next = proxy_data->node_list; node->prev = NULL; node->filename = filename; node->fileline = fileline; node->size = size; + + mutex_lock(proxy_data->mutex); + node->next = proxy_data->node_list; if(proxy_data->node_list) proxy_data->node_list->prev = node; proxy_data->node_list = node; + mutex_unlock(proxy_data->mutex); return mem; } @@ -474,6 +479,7 @@ proxy_free(void* data, void* mem) node = (void*)((uintptr_t)mem - ALIGN_SIZE(sizeof(struct mem_node), alignment)); + mutex_lock(proxy_data->mutex); if(node->prev) { node->prev->next = node->next; } @@ -483,6 +489,7 @@ proxy_free(void* data, void* mem) if(node->prev == NULL) { proxy_data->node_list = node->next; } + mutex_unlock(proxy_data->mutex); MEM_FREE(proxy_data->allocator, node); } } @@ -535,7 +542,7 @@ proxy_mem_size(void* data, void* mem) struct mem_node* node = (struct mem_node*) ((uintptr_t)mem - ALIGN_SIZE(sizeof(struct mem_node), alignment)); struct proxy_data* proxy_data = (struct proxy_data*)data; - ASSERT( data ); + ASSERT(data); return MEM_SIZE(proxy_data->allocator, node); } @@ -548,9 +555,11 @@ proxy_allocated_size(const void* data) ASSERT(data); proxy_data = data; + mutex_lock(proxy_data->mutex); for(node = proxy_data->node_list; node != NULL; node = node->next) { allocated_size += mem_size(node); } + mutex_unlock(proxy_data->mutex); return allocated_size; } @@ -568,6 +577,7 @@ proxy_dump ASSERT(data && (!max_dump_len || dump)); proxy_data = data; + mutex_lock(proxy_data->mutex); for(node = proxy_data->node_list; node != NULL; node = node->next) { if(dump) { const int len = snprintf @@ -591,6 +601,7 @@ proxy_dump } } } + mutex_unlock(proxy_data->mutex); return dump_len; } @@ -616,19 +627,29 @@ EXPORT_SYM struct mem_allocator mem_default_allocator = { /******************************************************************************* * Proxy allocator ******************************************************************************/ -void +res_T mem_init_proxy_allocator (struct mem_allocator* proxy_allocator, struct mem_allocator* allocator) { struct proxy_data* proxy_data = NULL; + res_T res = RES_OK; - if((!allocator) | (!proxy_allocator)) + if((!allocator) | (!proxy_allocator)) { + res = RES_BAD_ARG; goto error; + } proxy_data = MEM_CALLOC(allocator, 1, sizeof(struct proxy_data)); - if(!proxy_data) + if(!proxy_data) { + res = RES_MEM_ERR; + goto error; + } + proxy_data->mutex = mutex_create(); + if(!proxy_data->mutex) { + res = RES_MEM_ERR; goto error; + } proxy_data->allocator = allocator; proxy_data->node_list = NULL; @@ -643,12 +664,14 @@ mem_init_proxy_allocator proxy_allocator->data = (void*)proxy_data; exit: - return; + return res; error: - if(proxy_allocator) { - ASSERT(proxy_data == NULL); - memset(proxy_allocator, 0, sizeof(struct mem_allocator)); + if(proxy_data) { + if(proxy_data->mutex) mutex_destroy(proxy_data->mutex); + MEM_FREE(allocator, proxy_data); } + if(proxy_allocator) + memset(proxy_allocator, 0, sizeof(struct mem_allocator)); goto exit; } @@ -661,6 +684,7 @@ mem_shutdown_proxy_allocator(struct mem_allocator* proxy) ASSERT(proxy); proxy_data = proxy->data; ASSERT(proxy_data->node_list == NULL); + mutex_destroy(proxy_data->mutex); allocator = proxy_data->allocator; MEM_FREE(allocator, proxy_data); memset(proxy, 0, sizeof(struct mem_allocator)); diff --git a/src/mem_allocator.h b/src/mem_allocator.h @@ -117,7 +117,7 @@ RSYS_API size_t mem_allocated_size(void); /******************************************************************************* * Proxy allocator ******************************************************************************/ -RSYS_API void +RSYS_API res_T mem_init_proxy_allocator (struct mem_allocator* proxy, struct mem_allocator* allocator);