diff --git a/parsec/utils/zone_malloc.c b/parsec/utils/zone_malloc.c index 16dc90729..81dad5ccd 100644 --- a/parsec/utils/zone_malloc.c +++ b/parsec/utils/zone_malloc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The University of Tennessee and The University + * Copyright (c) 2012-2024 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. */ @@ -35,12 +35,12 @@ zone_malloc_t* zone_malloc_init(void* base_ptr, int _max_segment, size_t _unit_s } gdata = (zone_malloc_t*)malloc( sizeof(zone_malloc_t) ); - gdata->base = base_ptr; - gdata->unit_size = _unit_size; - gdata->max_segment = _max_segment; - - gdata->next_tid = 0; - gdata->segments = (segment_t *)malloc(sizeof(segment_t) * _max_segment); + gdata->base = base_ptr; + gdata->unit_size = _unit_size; + gdata->max_segment = _max_segment; + gdata->next_tid = 0; + gdata->segments = (segment_t *)malloc(sizeof(segment_t) * _max_segment); + parsec_atomic_lock_init(&gdata->lock); #if defined(PARSEC_DEBUG) for(int i = 0; i < _max_segment; i++) { SEGMENT_AT_TID(gdata, i)->status = SEGMENT_UNDEFINED; @@ -74,6 +74,7 @@ void *zone_malloc(zone_malloc_t *gdata, size_t size) int next_tid, current_tid, new_tid; int cycled_through = 0, nb_units; + parsec_atomic_lock(&gdata->lock); /* Let's start with the last remembered free slot */ current_tid = gdata->next_tid; nb_units = (size + gdata->unit_size - 1) / gdata->unit_size; @@ -82,13 +83,10 @@ void *zone_malloc(zone_malloc_t *gdata, size_t size) current_segment = SEGMENT_AT_TID(gdata, current_tid); if( NULL == current_segment ) { /* Maybe there is a free slot in the beginning. Let's cycle at least once before we bail out */ - if( cycled_through == 0 ) { - current_tid = 0; - cycled_through = 1; - current_segment = SEGMENT_AT_TID(gdata, current_tid); - } else { - return NULL; - } + if( 0 != cycled_through ) break; + current_tid = 0; + cycled_through = 1; + current_segment = SEGMENT_AT_TID(gdata, current_tid); } if( current_segment->status == SEGMENT_EMPTY && current_segment->nb_units >= nb_units ) { @@ -111,12 +109,14 @@ void *zone_malloc(zone_malloc_t *gdata, size_t size) current_segment->nb_units = nb_units; } + parsec_atomic_unlock(&gdata->lock); return (void*)(gdata->base + (current_tid * gdata->unit_size)); } current_tid += current_segment->nb_units; } while( current_tid != gdata->next_tid ); + parsec_atomic_unlock(&gdata->lock); return NULL; } @@ -126,6 +126,7 @@ void zone_free(zone_malloc_t *gdata, void *add) int current_tid, next_tid, prev_tid; off_t offset; + parsec_atomic_lock(&gdata->lock); offset = (char*)add -gdata->base; assert( (offset % gdata->unit_size) == 0); current_tid = offset / gdata->unit_size; @@ -133,11 +134,13 @@ void zone_free(zone_malloc_t *gdata, void *add) if( NULL == current_segment ) { zone_malloc_error("address to free not allocated\n"); + parsec_atomic_unlock(&gdata->lock); return; } if( SEGMENT_EMPTY == current_segment->status ) { zone_malloc_error("double free (or other buffer overflow) error in ZONE allocation"); + parsec_atomic_unlock(&gdata->lock); return; } @@ -173,6 +176,7 @@ void zone_free(zone_malloc_t *gdata, void *add) next_segment->nb_prev = current_segment->nb_units; } } + parsec_atomic_unlock(&gdata->lock); } size_t zone_in_use(zone_malloc_t *gdata) @@ -180,6 +184,7 @@ size_t zone_in_use(zone_malloc_t *gdata) size_t ret = 0; segment_t *current_segment; int current_tid; + parsec_atomic_lock(&gdata->lock); for(current_tid = 0; (current_segment = SEGMENT_AT_TID(gdata, current_tid)) != NULL; current_tid += current_segment->nb_units) { @@ -187,6 +192,7 @@ size_t zone_in_use(zone_malloc_t *gdata) ret += gdata->unit_size * current_segment->nb_units; } } + parsec_atomic_unlock(&gdata->lock); return ret; } @@ -197,6 +203,7 @@ size_t zone_debug(zone_malloc_t *gdata, int level, int output_id, const char *pr int current_tid; size_t ret = 0; + parsec_atomic_lock(&gdata->lock); for(current_tid = 0; (current_segment = SEGMENT_AT_TID(gdata, current_tid)) != NULL; current_tid += current_segment->nb_units) { @@ -217,6 +224,6 @@ size_t zone_debug(zone_malloc_t *gdata, int level, int output_id, const char *pr gdata->base + (current_tid+current_segment->nb_units) * gdata->unit_size - 1); } } - + parsec_atomic_unlock(&gdata->lock); return ret; } diff --git a/parsec/utils/zone_malloc.h b/parsec/utils/zone_malloc.h index ebf286beb..3529834e0 100644 --- a/parsec/utils/zone_malloc.h +++ b/parsec/utils/zone_malloc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The University of Tennessee and The University + * Copyright (c) 2012-2024 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. */ @@ -8,6 +8,7 @@ #define _ZONE_MALLOC_H_ #include "parsec/parsec_config.h" +#include "parsec/sys/atomic.h" #include #include @@ -30,6 +31,7 @@ typedef struct zone_malloc_s { size_t unit_size; /* Basic Unit */ int max_segment; /* Maximum number of segment */ int next_tid; /* Next TID to look at for a malloc */ + parsec_atomic_lock_t lock; } zone_malloc_t;