unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] realloc: Return unchanged if request is within usable size
@ 2022-11-25 20:09 Siddhesh Poyarekar via Libc-alpha
  2022-11-25 20:40 ` Andreas Schwab
  2022-11-28 17:26 ` [PATCH v2] " Siddhesh Poyarekar via Libc-alpha
  0 siblings, 2 replies; 13+ messages in thread
From: Siddhesh Poyarekar via Libc-alpha @ 2022-11-25 20:09 UTC (permalink / raw)
  To: libc-alpha

If there is enough space in the chunk to satisfy the new size, return
the old pointer as is, thus avoiding any locks or reallocations.  The
only real place this has a benefit is in large chunks that tend to get
satisfied with mmap, since there is a large enough spare size (up to a
page) for it to matter.  For allocations on heap, the extra size is
typically barely a few bytes (up to 15) and it's unlikely that it would
make much difference in performance.

Also added a smoke test to ensure that the old pointer is returned
unchanged if the new size to realloc is within usable size of the old
pointer.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
---
 malloc/malloc.c      |  6 ++++++
 malloc/tst-realloc.c | 21 +++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/malloc/malloc.c b/malloc/malloc.c
index 2a61c8b5ee..3ef61bef34 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1100,6 +1100,8 @@ static void munmap_chunk(mchunkptr p);
 static mchunkptr mremap_chunk(mchunkptr p, size_t new_size);
 #endif
 
+static size_t musable (void *mem);
+
 /* ------------------ MMAP support ------------------  */
 
 
@@ -3396,6 +3398,10 @@ __libc_realloc (void *oldmem, size_t bytes)
   if (__glibc_unlikely (mtag_enabled))
     *(volatile char*) oldmem;
 
+  /* If there's usable space in the current chunk, return as is.  */
+  if (bytes <= musable (oldmem))
+    return oldmem;
+
   /* chunk corresponding to oldmem */
   const mchunkptr oldp = mem2chunk (oldmem);
   /* its size */
diff --git a/malloc/tst-realloc.c b/malloc/tst-realloc.c
index 5eb62a770f..54dd0dd0b3 100644
--- a/malloc/tst-realloc.c
+++ b/malloc/tst-realloc.c
@@ -142,6 +142,27 @@ do_test (void)
 
   free (p);
 
+  /* Smoke test to make sure that allocations do not move if they have enough
+     space to expand in the chunk.  */
+  for (size_t sz = 3; sz < 256 * 1024; sz += 2048)
+    {
+      p = realloc (NULL, sz);
+      if (p == NULL)
+	FAIL_EXIT1 ("realloc (NULL, 31) returned NULL.");
+      size_t newsz = malloc_usable_size (p);
+      printf ("size: %zu, usable size: %zu, extra: %zu\n",
+	      sz, newsz, newsz - sz);
+      void *new_p = realloc (p, newsz);
+      if (new_p != p)
+	FAIL_EXIT1 ("Expanding (%zu bytes) to usable size (%zu) moved block",
+		    sz, newsz);
+      free (new_p);
+
+      /* We encountered a large enough extra size at least once.  */
+      if (newsz - sz > 1024)
+	break;
+    }
+
   return 0;
 }
 
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread
* [PATCH] realloc: Return unchanged if request is within usable size
@ 2022-11-28  9:22 Wilco Dijkstra via Libc-alpha
  2022-11-28 14:13 ` Siddhesh Poyarekar via Libc-alpha
  0 siblings, 1 reply; 13+ messages in thread
From: Wilco Dijkstra via Libc-alpha @ 2022-11-28  9:22 UTC (permalink / raw)
  To: 'GNU C Library'; +Cc: siddhesh@sourceware.org

Hi Siddhesh,

I think the idea of having a fast path in realloc is good since it is a more standard
interface than malloc_usable_size, so improving performance for obvious cases
where we can return the original pointer makes sense. It will help badly written
code that does a realloc when growing an array 1 element at a time.

However the proposed patch will block realloc from ever releasing memory...
We do need to handle the case where the size is smaller than the usable size since
we'd still want to free the unused portion if it is a significant fraction of the total size.
Note the mmap code always tries to remap before checking the new size is smaller
than usable size - so will end up remapping even if you downsize by one page.

Cheers,
Wilco

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2023-07-04 16:08 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-25 20:09 [PATCH] realloc: Return unchanged if request is within usable size Siddhesh Poyarekar via Libc-alpha
2022-11-25 20:40 ` Andreas Schwab
2022-11-28 14:23   ` Siddhesh Poyarekar via Libc-alpha
2022-11-28 14:29     ` Andreas Schwab
2022-11-28 17:26 ` [PATCH v2] " Siddhesh Poyarekar via Libc-alpha
2022-12-06 22:33   ` DJ Delorie via Libc-alpha
  -- strict thread matches above, loose matches on Subject: below --
2022-11-28  9:22 [PATCH] " Wilco Dijkstra via Libc-alpha
2022-11-28 14:13 ` Siddhesh Poyarekar via Libc-alpha
2022-12-06 12:45   ` Wilco Dijkstra via Libc-alpha
2022-12-06 18:41     ` Siddhesh Poyarekar via Libc-alpha
2023-07-03 22:02     ` Aurelien Jarno
2023-07-04 11:17       ` Siddhesh Poyarekar via Libc-alpha
2023-07-04 16:08         ` Aurelien Jarno

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).