Author: tross Date: Wed Nov 13 19:49:29 2013 New Revision: 1541679 URL: http://svn.apache.org/r1541679 Log: QPID-5339 - Fixed thread safety issue in the type allocator initialization - Added a memory test-mode to check for under/over-run of allocated space.
Modified: qpid/dispatch/trunk/include/qpid/dispatch/alloc.h qpid/dispatch/trunk/src/alloc.c Modified: qpid/dispatch/trunk/include/qpid/dispatch/alloc.h URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/include/qpid/dispatch/alloc.h?rev=1541679&r1=1541678&r2=1541679&view=diff ============================================================================== --- qpid/dispatch/trunk/include/qpid/dispatch/alloc.h (original) +++ qpid/dispatch/trunk/include/qpid/dispatch/alloc.h Wed Nov 13 19:49:29 2013 @@ -40,6 +40,7 @@ typedef struct { } dx_alloc_stats_t; typedef struct { + uint32_t header; char *type_name; size_t type_size; size_t *additional_size; @@ -48,6 +49,7 @@ typedef struct { dx_alloc_stats_t *stats; dx_alloc_pool_t *global_pool; sys_mutex_t *lock; + uint32_t trailer; } dx_alloc_type_desc_t; @@ -60,7 +62,7 @@ void dx_dealloc(dx_alloc_type_desc_t *de void free_##T(T *p) #define ALLOC_DEFINE_CONFIG(T,S,A,C) \ - dx_alloc_type_desc_t __desc_##T = {#T, S, A, 0, C, 0, 0, 0}; \ + dx_alloc_type_desc_t __desc_##T = {0, #T, S, A, 0, C, 0, 0, 0, 0}; \ __thread dx_alloc_pool_t *__local_pool_##T = 0; \ T *new_##T() { return (T*) dx_alloc(&__desc_##T, &__local_pool_##T); } \ void free_##T(T *p) { dx_dealloc(&__desc_##T, &__local_pool_##T, (void*) p); } \ Modified: qpid/dispatch/trunk/src/alloc.c URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/alloc.c?rev=1541679&r1=1541678&r2=1541679&view=diff ============================================================================== --- qpid/dispatch/trunk/src/alloc.c (original) +++ qpid/dispatch/trunk/src/alloc.c Wed Nov 13 19:49:29 2013 @@ -24,6 +24,8 @@ #include <memory.h> #include <stdio.h> +#define DX_MEMORY_DEBUG 1 + typedef struct dx_alloc_type_t dx_alloc_type_t; typedef struct dx_alloc_item_t dx_alloc_item_t; @@ -34,9 +36,15 @@ struct dx_alloc_type_t { DEQ_DECLARE(dx_alloc_type_t, dx_alloc_type_list_t); +#define PATTERN_FRONT 0xdeadbeef +#define PATTERN_BACK 0xbabecafe struct dx_alloc_item_t { DEQ_LINKS(dx_alloc_item_t); +#ifdef DX_MEMORY_DEBUG + dx_alloc_type_desc_t *desc; + uint32_t header; +#endif }; DEQ_DECLARE(dx_alloc_item_t, dx_alloc_item_list_t); @@ -50,21 +58,21 @@ dx_alloc_config_t dx_alloc_default_confi dx_alloc_config_t dx_alloc_default_config_small = {64, 128, 0}; #define BIG_THRESHOLD 256 -static sys_mutex_t *init_lock; +static sys_mutex_t *init_lock = 0; static dx_alloc_type_list_t type_list; static void dx_alloc_init(dx_alloc_type_desc_t *desc) { sys_mutex_lock(init_lock); - desc->total_size = desc->type_size; - if (desc->additional_size) - desc->total_size += *desc->additional_size; - //dx_log("ALLOC", LOG_TRACE, "Initialized Allocator - type=%s type-size=%d total-size=%d", // desc->type_name, desc->type_size, desc->total_size); if (!desc->global_pool) { + desc->total_size = desc->type_size; + if (desc->additional_size) + desc->total_size += *desc->additional_size; + if (desc->config == 0) desc->config = desc->total_size > BIG_THRESHOLD ? &dx_alloc_default_config_big : &dx_alloc_default_config_small; @@ -81,6 +89,9 @@ static void dx_alloc_init(dx_alloc_type_ DEQ_ITEM_INIT(type_item); type_item->desc = desc; DEQ_INSERT_TAIL(type_list, type_item); + + desc->header = PATTERN_FRONT; + desc->trailer = PATTERN_BACK; } sys_mutex_unlock(init_lock); @@ -94,7 +105,7 @@ void *dx_alloc(dx_alloc_type_desc_t *des // // If the descriptor is not initialized, set it up now. // - if (!desc->global_pool) + if (desc->trailer != PATTERN_BACK) dx_alloc_init(desc); // @@ -116,6 +127,11 @@ void *dx_alloc(dx_alloc_type_desc_t *des dx_alloc_item_t *item = DEQ_HEAD(pool->free_list); if (item) { DEQ_REMOVE_HEAD(pool->free_list); +#ifdef DX_MEMORY_DEBUG + item->desc = desc; + item->header = PATTERN_FRONT; + *((uint32_t*) ((void*) &item[1] + desc->total_size))= PATTERN_BACK; +#endif return &item[1]; } @@ -140,7 +156,11 @@ void *dx_alloc(dx_alloc_type_desc_t *des // Allocate a full batch from the heap and put it on the thread list. // for (idx = 0; idx < desc->config->transfer_batch_size; idx++) { - item = (dx_alloc_item_t*) malloc(sizeof(dx_alloc_item_t) + desc->total_size); + item = (dx_alloc_item_t*) malloc(sizeof(dx_alloc_item_t) + desc->total_size +#ifdef DX_MEMORY_DEBUG + + sizeof(uint32_t) +#endif + ); if (item == 0) break; DEQ_ITEM_INIT(item); @@ -154,6 +174,11 @@ void *dx_alloc(dx_alloc_type_desc_t *des item = DEQ_HEAD(pool->free_list); if (item) { DEQ_REMOVE_HEAD(pool->free_list); +#ifdef DX_MEMORY_DEBUG + item->desc = desc; + item->header = PATTERN_FRONT; + *((uint32_t*) ((void*) &item[1] + desc->total_size))= PATTERN_BACK; +#endif return &item[1]; } @@ -166,6 +191,15 @@ void dx_dealloc(dx_alloc_type_desc_t *de dx_alloc_item_t *item = ((dx_alloc_item_t*) p) - 1; int idx; +#ifdef DX_MEMORY_DEBUG + assert (desc->header == PATTERN_FRONT); + assert (desc->trailer == PATTERN_BACK); + assert (item->header == PATTERN_FRONT); + assert (*((uint32_t*) (p + desc->total_size)) == PATTERN_BACK); + assert (item->desc == desc); + item->desc = 0; +#endif + // // If this is the thread's first pass through here, allocate the // thread-local pool for this type. --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org