- Check malloc areana atomically

- Don't call reused_arena when _int_new_arena failed (#753601)
This commit is contained in:
Jeff Law 2011-11-20 21:30:51 -07:00
parent be07c4dc8b
commit 6d7f7445a9
1 changed files with 146 additions and 0 deletions

146
glibc-arenalock.patch Normal file
View File

@ -0,0 +1,146 @@
commit 77cdc054e02069d72dcf54a9ad7d7df3a24bcb01
Author: Andreas Schwab <schwab@redhat.com>
Date: Wed Nov 9 17:14:39 2011 +0100
Check malloc arana limit atomically
diff --git a/ChangeLog b/ChangeLog
index bf09161..edd7dd8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2011-11-14 Andreas Schwab <schwab@redhat.com>
+
+ * malloc/arena.c (arena_get2): Don't call reused_arena when
+ _int_new_arena failed.
+
+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-10-19 Andreas Schwab <schwab@redhat.com>
* sysdeps/x86_64/fpu/math_private.h (libc_feupdateenv): Use
diff --git a/malloc/arena.c b/malloc/arena.c
index 9114fd2..042cac8 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;
commit a5fb313cb7b7e692fd4684916aaa98e03ec7e8b6
Author: Andreas Schwab <schwab@redhat.com>
Date: Mon Nov 14 11:41:52 2011 +0100
Don't call reused_arena when _int_new_arena failed
diff --git a/malloc/arena.c b/malloc/arena.c
index 042cac8..cb8548b 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -844,14 +844,14 @@ arena_get2(mstate a_tsd, size_t size)
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))
+ 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);
+ if (__builtin_expect (a == NULL, 0))
+ catomic_decrement (&narenas);
}
- a = reused_arena ();
+ else
+ a = reused_arena ();
}
#else
if(!a_tsd)