aboutsummaryrefslogtreecommitdiff
path: root/malloc/arena.c
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@redhat.com>2012-09-07 14:39:52 +0530
committerSiddhesh Poyarekar <siddhesh@redhat.com>2012-09-07 14:40:58 +0530
commitc78ab0947353c8f46d23857ebf3fb4a70ed581d9 (patch)
treebfe0fa498ef6ea5c98a1ed81cbc2cdecef6b9dde /malloc/arena.c
parent01f49f59cebf782c663698a0fa6f15453409d42b (diff)
downloadglibc-c78ab0947353c8f46d23857ebf3fb4a70ed581d9.tar
glibc-c78ab0947353c8f46d23857ebf3fb4a70ed581d9.tar.gz
glibc-c78ab0947353c8f46d23857ebf3fb4a70ed581d9.tar.bz2
glibc-c78ab0947353c8f46d23857ebf3fb4a70ed581d9.zip
Cleanup code duplication in malloc on fallback to use another arena
Break the fallback code to try another arena into a separate function for readability.
Diffstat (limited to 'malloc/arena.c')
-rw-r--r--malloc/arena.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/malloc/arena.c b/malloc/arena.c
index b893baeb43..97c0b909cc 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -917,6 +917,27 @@ arena_get2(mstate a_tsd, size_t size, mstate avoid_arena)
return a;
}
+/* If we don't have the main arena, then maybe the failure is due to running
+ out of mmapped areas, so we can try allocating on the main arena.
+ Otherwise, it is likely that sbrk() has failed and there is still a chance
+ to mmap(), so try one of the other arenas. */
+static mstate
+arena_get_retry (mstate ar_ptr, size_t bytes)
+{
+ if(ar_ptr != &main_arena) {
+ (void)mutex_unlock(&ar_ptr->mutex);
+ ar_ptr = &main_arena;
+ (void)mutex_lock(&ar_ptr->mutex);
+ } else {
+ /* Grab ar_ptr->next prior to releasing its lock. */
+ mstate prev = ar_ptr->next ? ar_ptr : 0;
+ (void)mutex_unlock(&ar_ptr->mutex);
+ ar_ptr = arena_get2(prev, bytes, ar_ptr);
+ }
+
+ return ar_ptr;
+}
+
#ifdef PER_THREAD
static void __attribute__ ((section ("__libc_thread_freeres_fn")))
arena_thread_freeres (void)