X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/1f50f809c4d885ff2b2c1a626d69ebb4cea0502f..6d2f9a6f0b14d7fe1f51dfe3b576a9bf2397ddb5:/src/xbt/mallocator.c diff --git a/src/xbt/mallocator.c b/src/xbt/mallocator.c index e4abe0de7f..10883555b9 100644 --- a/src/xbt/mallocator.c +++ b/src/xbt/mallocator.c @@ -38,8 +38,30 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_mallocator, xbt, "Mallocators"); * some mallocators internally... */ - +/* Value != 0 when the framework configuration is done. Value > 1 if the + * mallocators should be protected from concurrent accesses. */ static int initialization_done = 0; + +static XBT_INLINE void lock_reset(xbt_mallocator_t m) +{ + m->lock = 0; +} + +static XBT_INLINE void lock_acquire(xbt_mallocator_t m) +{ + if (initialization_done > 1) { + int *lock = &m->lock; + while (__sync_lock_test_and_set(lock, 1)) + /* nop */; + } +} + +static XBT_INLINE void lock_release(xbt_mallocator_t m) +{ + if (initialization_done > 1) + __sync_lock_release(&m->lock); +} + /** * This function must be called once the framework configuration is done. If not, * mallocators will never get used. Check the implementation notes in @@ -48,16 +70,17 @@ static int initialization_done = 0; * For example, surf_config uses this function to tell to the mallocators that * the simgrid * configuration is now finished and that it can create them if not done yet */ -void xbt_mallocator_initialization_is_done(void) { - initialization_done = 1; +void xbt_mallocator_initialization_is_done(int protect) +{ + initialization_done = protect ? 2 : 1; } /** used by the module to know if it's time to activate the mallocators yet */ static XBT_INLINE int xbt_mallocator_is_active(void) { -#ifndef MALLOCATOR_COMPILED_IN - return 0; -#else +#if MALLOCATOR_COMPILED_IN return initialization_done && !MC_is_active(); +#else + return 0; #endif } @@ -120,7 +143,6 @@ void xbt_mallocator_free(xbt_mallocator_t m) m->free_f(m->objects[i]); } xbt_free(m->objects); - xbt_os_mutex_destroy(m->mutex); xbt_free(m); } @@ -145,7 +167,7 @@ void *xbt_mallocator_get(xbt_mallocator_t m) void *object; if (m->objects != NULL) { // this mallocator is active, stop thinking and go for it! - xbt_os_mutex_acquire(m->mutex); + lock_acquire(m); if (m->current_size <= 0) { /* No object is ready yet. Create a bunch of them to try to group the * mallocs on the same memory pages (to help the cache lines) */ @@ -163,12 +185,12 @@ void *xbt_mallocator_get(xbt_mallocator_t m) /* XBT_DEBUG("Reuse an old object for mallocator %p (size:%d/%d)", */ /* m, m->current_size, m->max_size); */ object = m->objects[--m->current_size]; - xbt_os_mutex_release(m->mutex); + lock_release(m); } else { if (xbt_mallocator_is_active()) { // We have to switch this mallocator from inactive to active (and then get an object) m->objects = xbt_new0(void *, m->max_size); - m->mutex = xbt_os_mutex_init(); + lock_reset(m); return xbt_mallocator_get(m); } else { object = m->new_f(); @@ -196,16 +218,16 @@ void *xbt_mallocator_get(xbt_mallocator_t m) void xbt_mallocator_release(xbt_mallocator_t m, void *object) { if (m->objects != NULL) { // Go for it - xbt_os_mutex_acquire(m->mutex); + lock_acquire(m); if (m->current_size < m->max_size) { /* there is enough place to push the object */ /* XBT_DEBUG ("Store deleted object in mallocator %p for further use (size:%d/%d)", m, m->current_size, m->max_size); */ m->objects[m->current_size++] = object; - xbt_os_mutex_release(m->mutex); + lock_release(m); } else { - xbt_os_mutex_release(m->mutex); + lock_release(m); /* otherwise we don't have a choice, we must free the object */ /* XBT_DEBUG("Free deleted object: mallocator %p is full (size:%d/%d)", m, m->current_size, m->max_size); */ @@ -215,7 +237,7 @@ void xbt_mallocator_release(xbt_mallocator_t m, void *object) if (xbt_mallocator_is_active()) { // We have to switch this mallocator from inactive to active (and then store that object) m->objects = xbt_new0(void *, m->max_size); - m->mutex = xbt_os_mutex_init(); + lock_reset(m); xbt_mallocator_release(m,object); } else { m->free_f(object);