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:
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);