This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] malloc: turn arena_get() into a function
- From: Joern Engel <joern at purestorage dot com>
- To: "GNU C. Library" <libc-alpha at sourceware dot org>
- Cc: Siddhesh Poyarekar <siddhesh dot poyarekar at gmail dot com>, Joern Engel <joern at purestorage dot org>
- Date: Mon, 25 Jan 2016 16:24:56 -0800
- Subject: [PATCH] malloc: turn arena_get() into a function
- Authentication-results: sourceware.org; auth=none
- References: <1453767942-19369-1-git-send-email-joern at purestorage dot com>
From: Joern Engel <joern@purestorage.org>
Macros may have made sense in the '90s. Not anymore.
JIRA: PURE-27597
---
tpc/malloc2.13/arena.h | 79 ++++++++++++++++++++++---------------------------
tpc/malloc2.13/malloc.c | 14 ++++-----
2 files changed, 43 insertions(+), 50 deletions(-)
diff --git a/tpc/malloc2.13/arena.h b/tpc/malloc2.13/arena.h
index 47ecf9421a46..0a269715004c 100644
--- a/tpc/malloc2.13/arena.h
+++ b/tpc/malloc2.13/arena.h
@@ -94,46 +94,6 @@ static int __malloc_initialized = -1;
/**************************************************************************/
-/*
- * Calling getcpu() for every allocation is too expensive - but we can turn
- * the syscall into a pointer dereference to a kernel shared memory page.
- */
-#include <sys/syscall.h>
-static inline int getnode(void)
-{
- int node, ret;
- ret = syscall(SYS_getcpu, NULL, &node, NULL);
- return (ret == -1) ? 0 : node;
-}
-
-/* arena_get() acquires an arena and locks the corresponding mutex.
- First, try the one last locked successfully by this thread. (This
- is the common case and handled with a macro for speed.) Then, loop
- once over the circularly linked list of arenas. If no arena is
- readily available, create a new one. In this latter case, `size'
- is just a hint as to how much memory will be required immediately
- in the new arena. */
-
-#define arena_get(ptr, size) do { \
- arena_lookup(ptr); \
- arena_lock(ptr, size); \
-} while(0)
-
-#define arena_lookup(ptr) do { \
- Void_t *vptr = NULL; \
- int node = getnode(); \
- ptr = (struct malloc_state *)tsd_getspecific(arena_key, vptr); \
- if (!ptr || ptr->numa_node != node) \
- ptr = numa_arena[node]; \
-} while(0)
-
-#define arena_lock(ptr, size) do { \
- if(ptr && !mutex_trylock(&ptr->mutex)) { \
- THREAD_STAT(++(ptr->stat_lock_direct)); \
- } else \
- ptr = arena_get2(ptr, (size)); \
-} while(0)
-
/* find the heap and corresponding arena for a given ptr */
#define heap_for_ptr(ptr) \
@@ -702,9 +662,7 @@ static struct malloc_state *_int_new_arena(size_t size, int numa_node)
return a;
}
-
-
-static struct malloc_state *internal_function arena_get2(struct malloc_state *a_tsd, size_t size)
+static struct malloc_state *arena_get2(struct malloc_state *a_tsd, size_t size)
{
struct malloc_state *a;
@@ -746,3 +704,38 @@ static struct malloc_state *internal_function arena_get2(struct malloc_state *a_
return a;
}
+
+/*
+ * Calling getcpu() for every allocation is too expensive - but we can turn
+ * the syscall into a pointer dereference to a kernel shared memory page.
+ */
+#include <sys/syscall.h>
+static inline int getnode(void)
+{
+ int node, ret;
+ ret = syscall(SYS_getcpu, NULL, &node, NULL);
+ return (ret == -1) ? 0 : node;
+}
+
+/* arena_get() acquires an arena and locks the corresponding mutex.
+ First, try the one last locked successfully by this thread. (This
+ is the common case and handled with a macro for speed.) Then, loop
+ once over the circularly linked list of arenas. If no arena is
+ readily available, create a new one. In this latter case, `size'
+ is just a hint as to how much memory will be required immediately
+ in the new arena. */
+
+static struct malloc_state *arena_get(size_t size)
+{
+ struct malloc_state *arena = NULL;
+ int node = getnode();
+
+ arena = pthread_getspecific(arena_key);
+ if (!arena || arena->numa_node != node)
+ arena = numa_arena[node];
+ if (arena && !mutex_trylock(&arena->mutex)) {
+ THREAD_STAT(++(arena->stat_lock_direct));
+ } else
+ arena = arena_get2(arena, size);
+ return arena;
+}
diff --git a/tpc/malloc2.13/malloc.c b/tpc/malloc2.13/malloc.c
index 11f050acebb1..b86f0c3ff65c 100644
--- a/tpc/malloc2.13/malloc.c
+++ b/tpc/malloc2.13/malloc.c
@@ -3354,7 +3354,7 @@ Void_t *public_mALLOc(size_t bytes)
if (__builtin_expect(hook != NULL, 0))
return (*hook) (bytes, RETURN_ADDRESS(0));
- arena_get(ar_ptr, bytes);
+ ar_ptr = arena_get(bytes);
if (!ar_ptr)
return 0;
victim = _int_malloc(ar_ptr, bytes);
@@ -3543,7 +3543,7 @@ Void_t *public_mEMALIGn(size_t alignment, size_t bytes)
if (alignment < MINSIZE)
alignment = MINSIZE;
- arena_get(ar_ptr, bytes + alignment + MINSIZE);
+ ar_ptr = arena_get(bytes + alignment + MINSIZE);
if (!ar_ptr)
return 0;
p = _int_memalign(ar_ptr, alignment, bytes);
@@ -3570,7 +3570,7 @@ Void_t *public_vALLOc(size_t bytes)
if (__builtin_expect(hook != NULL, 0))
return (*hook) (pagesz, bytes, RETURN_ADDRESS(0));
- arena_get(ar_ptr, bytes + pagesz + MINSIZE);
+ ar_ptr = arena_get(bytes + pagesz + MINSIZE);
if (!ar_ptr)
return 0;
p = _int_valloc(ar_ptr, bytes);
@@ -3601,7 +3601,7 @@ Void_t *public_pVALLOc(size_t bytes)
if (__builtin_expect(hook != NULL, 0))
return (*hook) (pagesz, rounded_bytes, RETURN_ADDRESS(0));
- arena_get(ar_ptr, bytes + 2 * pagesz + MINSIZE);
+ ar_ptr = arena_get(bytes + 2 * pagesz + MINSIZE);
p = _int_pvalloc(ar_ptr, bytes);
(void)mutex_unlock(&ar_ptr->mutex);
if (!p) {
@@ -3652,7 +3652,7 @@ Void_t *public_cALLOc(size_t n, size_t elem_size)
sz = bytes;
- arena_get(av, sz);
+ av = arena_get(sz);
if (!av)
return 0;
@@ -3739,7 +3739,7 @@ public_iCALLOc(size_t n, size_t elem_size, Void_t** chunks)
struct malloc_state * ar_ptr;
Void_t** m;
- arena_get(ar_ptr, n*elem_size);
+ ar_ptr = arena_get(n*elem_size);
if(!ar_ptr)
return 0;
@@ -3754,7 +3754,7 @@ public_iCOMALLOc(size_t n, size_t sizes[], Void_t** chunks)
struct malloc_state * ar_ptr;
Void_t** m;
- arena_get(ar_ptr, 0);
+ ar_ptr = arena_get(0);
if(!ar_ptr)
return 0;
--
2.7.0.rc3