public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] msort: Get rid of alloca.
@ 2023-06-30 17:26 Joe Simmons-Talbott
  2023-06-30 20:12 ` Paul Eggert
  2023-07-03 18:25 ` Joe Simmons-Talbott
  0 siblings, 2 replies; 8+ messages in thread
From: Joe Simmons-Talbott @ 2023-06-30 17:26 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joe Simmons-Talbott

Use a scratch_buffer rather than alloca/malloc to avoid potential stack
overflow.
---
 stdlib/msort.c | 94 +++++++++++++++++++++++---------------------------
 1 file changed, 43 insertions(+), 51 deletions(-)

diff --git a/stdlib/msort.c b/stdlib/msort.c
index bbaa5e9f82..237dbb444f 100644
--- a/stdlib/msort.c
+++ b/stdlib/msort.c
@@ -24,6 +24,7 @@
 #include <memcopy.h>
 #include <errno.h>
 #include <atomic.h>
+#include <scratch_buffer.h>
 
 struct msort_param
 {
@@ -164,71 +165,62 @@ void
 __qsort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg)
 {
   size_t size = n * s;
-  char *tmp = NULL;
   struct msort_param p;
+  struct scratch_buffer buf;
+  scratch_buffer_init (&buf);
 
   /* For large object sizes use indirect sorting.  */
   if (s > 32)
     size = 2 * n * sizeof (void *) + s;
 
-  if (size < 1024)
-    /* The temporary array is small, so put it on the stack.  */
-    p.t = __alloca (size);
-  else
-    {
-      /* We should avoid allocating too much memory since this might
-	 have to be backed up by swap space.  */
-      static long int phys_pages;
-      static int pagesize;
+  /* We should avoid allocating too much memory since this might
+     have to be backed up by swap space.  */
+  static long int phys_pages;
+  static int pagesize;
 
-      if (pagesize == 0)
-	{
-	  phys_pages = __sysconf (_SC_PHYS_PAGES);
+  if (pagesize == 0)
+    {
+      phys_pages = __sysconf (_SC_PHYS_PAGES);
 
-	  if (phys_pages == -1)
-	    /* Error while determining the memory size.  So let's
-	       assume there is enough memory.  Otherwise the
-	       implementer should provide a complete implementation of
-	       the `sysconf' function.  */
-	    phys_pages = (long int) (~0ul >> 1);
+      if (phys_pages == -1)
+        /* Error while determining the memory size.  So let's
+           assume there is enough memory.  Otherwise the
+           implementer should provide a complete implementation of
+           the `sysconf' function.  */
+        phys_pages = (long int) (~0ul >> 1);
 
-	  /* The following determines that we will never use more than
-	     a quarter of the physical memory.  */
-	  phys_pages /= 4;
+      /* The following determines that we will never use more than
+         a quarter of the physical memory.  */
+      phys_pages /= 4;
 
-	  /* Make sure phys_pages is written to memory.  */
-	  atomic_write_barrier ();
+      /* Make sure phys_pages is written to memory.  */
+      atomic_write_barrier ();
 
-	  pagesize = __sysconf (_SC_PAGESIZE);
-	}
+      pagesize = __sysconf (_SC_PAGESIZE);
+    }
 
-      /* Just a comment here.  We cannot compute
-	   phys_pages * pagesize
-	   and compare the needed amount of memory against this value.
-	   The problem is that some systems might have more physical
-	   memory then can be represented with a `size_t' value (when
-	   measured in bytes.  */
+  /* Just a comment here.  We cannot compute
+       phys_pages * pagesize
+       and compare the needed amount of memory against this value.
+       The problem is that some systems might have more physical
+       memory then can be represented with a `size_t' value (when
+       measured in bytes.  */
 
-      /* If the memory requirements are too high don't allocate memory.  */
-      if (size / pagesize > (size_t) phys_pages)
-	{
-	  _quicksort (b, n, s, cmp, arg);
-	  return;
-	}
+  /* If the memory requirements are too high don't allocate memory.  */
+  if (size / pagesize > (size_t) phys_pages)
+    {
+      _quicksort (b, n, s, cmp, arg);
+      return;
+    }
 
-      /* It's somewhat large, so malloc it.  */
-      int save = errno;
-      tmp = malloc (size);
-      __set_errno (save);
-      if (tmp == NULL)
-	{
-	  /* Couldn't get space, so use the slower algorithm
-	     that doesn't need a temporary array.  */
-	  _quicksort (b, n, s, cmp, arg);
-	  return;
-	}
-      p.t = tmp;
+  if (!scratch_buffer_set_array_size (&buf, 1, size))
+    {
+      /* Couldn't get space, so use the slower algorithm
+         that doesn't need a temporary array.  */
+      _quicksort (b, n, s, cmp, arg);
+      return;
     }
+  p.t = buf.data;
 
   p.s = s;
   p.var = 4;
@@ -295,7 +287,7 @@ __qsort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg)
 	}
       msort_with_tmp (&p, b, n);
     }
-  free (tmp);
+  scratch_buffer_free (&buf);
 }
 libc_hidden_def (__qsort_r)
 weak_alias (__qsort_r, qsort_r)
-- 
2.39.2


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

end of thread, other threads:[~2023-07-07 13:56 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-30 17:26 [PATCH] msort: Get rid of alloca Joe Simmons-Talbott
2023-06-30 20:12 ` Paul Eggert
2023-07-03 16:08   ` Joe Simmons-Talbott
2023-07-06 13:43     ` Adhemerval Zanella Netto
2023-07-06 19:17       ` Joe Simmons-Talbott
2023-07-06 19:29         ` Xi Ruoyao
2023-07-07 13:56           ` Adhemerval Zanella Netto
2023-07-03 18:25 ` Joe Simmons-Talbott

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).