diff options
author | Andreas Schwab <schwab@redhat.com> | 2011-11-09 17:14:39 +0100 |
---|---|---|
committer | Andreas Schwab <schwab@redhat.com> | 2011-11-10 11:00:59 +0100 |
commit | 77cdc054e02069d72dcf54a9ad7d7df3a24bcb01 (patch) | |
tree | 9556e4989739f6c40f92860f2119375b8d6caec0 | |
parent | 5f078c3286c177a4d66ad89e7b3930e2d6132586 (diff) | |
download | glibc-77cdc054e02069d72dcf54a9ad7d7df3a24bcb01.tar.gz glibc-77cdc054e02069d72dcf54a9ad7d7df3a24bcb01.tar.xz glibc-77cdc054e02069d72dcf54a9ad7d7df3a24bcb01.zip |
Check malloc arana limit atomically
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | malloc/arena.c | 65 |
2 files changed, 41 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog index bf091611c0..edd7dd8a96 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-11-10 Andreas Schwab <schwab@redhat.com> + + * malloc/arena.c (_int_new_arena): Don't increment narenas. + (reused_arena): Don't check arena limit. + (arena_get2): Atomically check arena limit. + 2011-11-08 Ulrich Drepper <drepper@gmail.com> * locale/findlocale.c (_nl_find_locale): Use __strcasecmp_l. diff --git a/malloc/arena.c b/malloc/arena.c index 9114fd28e9..042cac85c0 100644 --- a/malloc/arena.c +++ b/malloc/arena.c @@ -747,8 +747,6 @@ _int_new_arena(size_t size) main_arena.next = a; #ifdef PER_THREAD - ++narenas; - (void)mutex_unlock(&list_lock); #endif @@ -786,30 +784,6 @@ get_free_list (void) static mstate reused_arena (void) { - if (narenas <= mp_.arena_test) - return NULL; - - static int narenas_limit; - if (narenas_limit == 0) - { - if (mp_.arena_max != 0) - narenas_limit = mp_.arena_max; - else - { - int n = __get_nprocs (); - - if (n >= 1) - narenas_limit = NARENAS_FROM_NCORES (n); - else - /* We have no information about the system. Assume two - cores. */ - narenas_limit = NARENAS_FROM_NCORES (2); - } - } - - if (narenas < narenas_limit) - return NULL; - mstate result; static mstate next_to_use; if (next_to_use == NULL) @@ -844,10 +818,41 @@ arena_get2(mstate a_tsd, size_t size) mstate a; #ifdef PER_THREAD - if ((a = get_free_list ()) == NULL - && (a = reused_arena ()) == NULL) - /* Nothing immediately available, so generate a new arena. */ - a = _int_new_arena(size); + static size_t narenas_limit; + + a = get_free_list (); + if (a == NULL) + { + /* Nothing immediately available, so generate a new arena. */ + if (narenas_limit == 0) + { + if (mp_.arena_max != 0) + narenas_limit = mp_.arena_max; + else + { + int n = __get_nprocs (); + + if (n >= 1) + narenas_limit = NARENAS_FROM_NCORES (n); + else + /* We have no information about the system. Assume two + cores. */ + narenas_limit = NARENAS_FROM_NCORES (2); + } + } + repeat:; + size_t n = narenas; + if (__builtin_expect (n <= mp_.arena_test || n < narenas_limit, 0)) + { + if (catomic_compare_and_exchange_bool_acq(&narenas, n + 1, n)) + goto repeat; + a = _int_new_arena (size); + if (__builtin_expect (a != NULL, 1)) + return a; + catomic_decrement(&narenas); + } + a = reused_arena (); + } #else if(!a_tsd) a = a_tsd = &main_arena; |