[v3,2/5] malloc: Avoid func call for tcache quick path in free()

Message ID 20240829062732.1663342-3-wangyang.guo@intel.com
State Under Review
Delegated to: Florian Weimer
Headers
Series malloc: TCACHE improvement for free and calloc |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Test passed

Commit Message

Guo, Wangyang Aug. 29, 2024, 6:27 a.m. UTC
  Tcache is an important optimzation to accelerate memory free(), things
within this code path should be kept as simple as possible. This commit
try to remove the function call when free() invokes tcache code path.

Result of bench-malloc-thread benchmark

Test Platform: Xeon-8380
Ratio: New / Original time_per_iteration (Lower is Better)

Threads#   | Ratio
-----------|------
1 thread   | 0.904
4 threads  | 0.919

The performance data shows it can improve bench-malloc-thread benchmark
by ~10% in single thread and ~8% in multi-thread scenario.

---
Changes in v2:
- _int_free_check() should be put outside of USE_TCACHE.
- Link to v1: https://sourceware.org/pipermail/libc-alpha/2024-August/159359.html
---
 malloc/malloc.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
  

Patch

diff --git a/malloc/malloc.c b/malloc/malloc.c
index ef49a13ea7..264f35e1a3 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -3448,7 +3448,17 @@  __libc_free (void *mem)
       (void)tag_region (chunk2mem (p), memsize (p));
 
       ar_ptr = arena_for_chunk (p);
-      _int_free (ar_ptr, p, 0);
+      INTERNAL_SIZE_T size = chunksize (p);
+      _int_free_check (ar_ptr, p, size);
+
+#if USE_TCACHE
+      if (tcache_free (p, size))
+	{
+	  __set_errno (err);
+	  return;
+	}
+#endif
+      _int_free_chunk (ar_ptr, p, size, 0);
     }
 
   __set_errno (err);