This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH 5/5] Add single-threaded path to _int_malloc
- From: Wilco Dijkstra <Wilco dot Dijkstra at arm dot com>
- To: "libc-alpha at sourceware dot org" <libc-alpha at sourceware dot org>
- Cc: nd <nd at arm dot com>
- Date: Thu, 12 Oct 2017 09:35:49 +0000
- Subject: [PATCH 5/5] Add single-threaded path to _int_malloc
- Authentication-results: sourceware.org; auth=none
- Authentication-results: spf=none (sender IP is ) smtp.mailfrom=Wilco dot Dijkstra at arm dot com;
- Nodisclaimer: True
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:99
This patch adds a single-threaded fast path to _int_malloc.
Since the goal is to use a single test to skip multiple atomic
operations, some of the fastbin allocation code has to be
duplicated.
Passes GLIBC tests, OK for commit?
ChangeLog:
2017-10-11 Wilco Dijkstra <wdijkstr@arm.com>
* malloc/malloc.c (_int_malloc): Add SINGLE_THREAD_P path.
--
diff --git a/malloc/malloc.c b/malloc/malloc.c
index f4f44400d120188c4d0bece996380e04b35c8fac..11fb93fbc983d5895ea05a9c9dc262d2d9d8923c 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -3565,37 +3565,77 @@ _int_malloc (mstate av, size_t bytes)
{
idx = fastbin_index (nb);
mfastbinptr *fb = &fastbin (av, idx);
- mchunkptr pp = *fb;
- REMOVE_FB (fb, victim, pp);
- if (victim != 0)
- {
- if (__builtin_expect (fastbin_index (chunksize (victim)) != idx, 0))
- malloc_printerr ("malloc(): memory corruption (fast)");
- check_remalloced_chunk (av, victim, nb);
-#if USE_TCACHE
- /* While we're here, if we see other chunks of the same size,
- stash them in the tcache. */
- size_t tc_idx = csize2tidx (nb);
- if (tcache && tc_idx < mp_.tcache_bins)
- {
- mchunkptr tc_victim;
+ mchunkptr next;
- /* While bin not empty and tcache not full, copy chunks over. */
- while (tcache->counts[tc_idx] < mp_.tcache_count
- && (pp = *fb) != NULL)
+ if (SINGLE_THREAD_P)
+ {
+ victim = *fb;
+ if (victim != NULL)
+ {
+ size_t victim_idx = fastbin_index (chunksize (victim));
+ next = victim->fd;
+ if (__builtin_expect (victim_idx != idx, 0))
+ malloc_printerr ("malloc(): memory corruption (fast)");
+ check_remalloced_chunk (av, victim, nb);
+#if USE_TCACHE
+ /* While we're here, if we see other chunks of the same size,
+ stash them in the tcache. */
+ size_t tc_idx = csize2tidx (nb);
+ if (next != NULL && tcache && tc_idx < mp_.tcache_bins)
{
- REMOVE_FB (fb, tc_victim, pp);
- if (tc_victim != 0)
+ mchunkptr tc_victim;
+
+ /* While bin not empty and tcache not full, copy chunks. */
+ while (tcache->counts[tc_idx] < mp_.tcache_count)
{
+ tc_victim = next;
+ next = tc_victim->fd;
tcache_put (tc_victim, tc_idx);
- }
+ if (next == NULL)
+ break;
+ }
}
- }
#endif
- void *p = chunk2mem (victim);
- alloc_perturb (p, bytes);
- return p;
+ *fb = next;
+ void *p = chunk2mem (victim);
+ alloc_perturb (p, bytes);
+ return p;
+ }
}
+ else
+ {
+ next = *fb;
+ REMOVE_FB (fb, victim, next);
+ if (victim != 0)
+ {
+ size_t victim_idx = fastbin_index (chunksize (victim));
+ if (__builtin_expect (victim_idx != idx, 0))
+ malloc_printerr ("malloc(): memory corruption (fast)");
+ check_remalloced_chunk (av, victim, nb);
+#if USE_TCACHE
+ /* While we're here, if we see other chunks of the same size,
+ stash them in the tcache. */
+ size_t tc_idx = csize2tidx (nb);
+ if (tcache && tc_idx < mp_.tcache_bins)
+ {
+ mchunkptr tc_victim;
+
+ /* While bin not empty and tcache not full, copy chunks. */
+ while (tcache->counts[tc_idx] < mp_.tcache_count
+ && (next = *fb) != NULL)
+ {
+ REMOVE_FB (fb, tc_victim, next);
+ if (tc_victim == NULL)
+ break;
+ tcache_put (tc_victim, tc_idx);
+ }
+ }
+#endif
+ void *p = chunk2mem (victim);
+ alloc_perturb (p, bytes);
+ return p;
+ }
+ }
}
/*