diff options
author | Jakub Jelinek <jakub@redhat.com> | 2004-12-13 23:32:37 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2004-12-13 23:32:37 +0000 |
commit | f9626feb2d8a692e27d1c020beba198ec52a705a (patch) | |
tree | 80e2799fe980f5c79a6bce099548081def04da41 /malloc/arena.c | |
parent | e797f2e35cbf7edf2c7de7f79442bda550917f07 (diff) | |
download | glibc-f9626feb2d8a692e27d1c020beba198ec52a705a.tar.gz glibc-f9626feb2d8a692e27d1c020beba198ec52a705a.tar.xz glibc-f9626feb2d8a692e27d1c020beba198ec52a705a.zip |
Updated to fedora-glibc-20041213T2323 cvs/fedora-glibc-2_3_3-91
Diffstat (limited to 'malloc/arena.c')
-rw-r--r-- | malloc/arena.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/malloc/arena.c b/malloc/arena.c index 024e191b9e..026f2c7822 100644 --- a/malloc/arena.c +++ b/malloc/arena.c @@ -782,9 +782,12 @@ arena_get2(a_tsd, size) mstate a_tsd; size_t size; } /* Check the global, circularly linked list for available arenas. */ + bool retried = false; repeat: do { if(!mutex_trylock(&a->mutex)) { + if (retried) + (void)mutex_unlock(&list_lock); THREAD_STAT(++(a->stat_lock_loop)); tsd_setspecific(arena_key, (Void_t *)a); return a; @@ -796,29 +799,33 @@ arena_get2(a_tsd, size) mstate a_tsd; size_t size; happen during `atfork', or for example on systems where thread creation makes it temporarily impossible to obtain _any_ locks. */ - if(mutex_trylock(&list_lock)) { + if(!retried && mutex_trylock(&list_lock)) { + /* We will block to not run in a busy loop. */ + (void)mutex_lock(&list_lock); + + /* Since we blocked there might be an arena available now. */ + retried = true; a = a_tsd; goto repeat; } - (void)mutex_unlock(&list_lock); /* Nothing immediately available, so generate a new arena. */ a = _int_new_arena(size); - if(!a) - return 0; + if(a) + { + tsd_setspecific(arena_key, (Void_t *)a); + mutex_init(&a->mutex); + mutex_lock(&a->mutex); /* remember result */ - tsd_setspecific(arena_key, (Void_t *)a); - mutex_init(&a->mutex); - mutex_lock(&a->mutex); /* remember result */ + /* Add the new arena to the global list. */ + a->next = main_arena.next; + atomic_write_barrier (); + main_arena.next = a; - /* Add the new arena to the global list. */ - (void)mutex_lock(&list_lock); - a->next = main_arena.next; - atomic_write_barrier (); - main_arena.next = a; + THREAD_STAT(++(a->stat_lock_loop)); + } (void)mutex_unlock(&list_lock); - THREAD_STAT(++(a->stat_lock_loop)); return a; } |