[04/25] sched_setaffinity (Linux variant): Rewrite to use VLA instead of alloca
diff mbox

Message ID 206ddd5496c544ce29259ef18f4cbadc6fe0619e.1425285061.git.fweimer@redhat.com
State New
Headers show

Commit Message

Florian Weimer March 1, 2015, 2:05 p.m. UTC
extend_alloca was used to emulate VLA deallocation.
---
 sysdeps/unix/sysv/linux/sched_setaffinity.c | 37 ++++++++++++++++-------------
 1 file changed, 20 insertions(+), 17 deletions(-)

Patch
diff mbox

diff --git a/sysdeps/unix/sysv/linux/sched_setaffinity.c b/sysdeps/unix/sysv/linux/sched_setaffinity.c
index b528617..a9299d8 100644
--- a/sysdeps/unix/sysv/linux/sched_setaffinity.c
+++ b/sysdeps/unix/sysv/linux/sched_setaffinity.c
@@ -22,7 +22,6 @@ 
 #include <unistd.h>
 #include <sys/types.h>
 #include <shlib-compat.h>
-#include <alloca.h>
 
 
 #ifdef __NR_sched_setaffinity
@@ -34,25 +33,29 @@  __sched_setaffinity_new (pid_t pid, size_t cpusetsize, const cpu_set_t *cpuset)
 {
   if (__glibc_unlikely (__kernel_cpumask_size == 0))
     {
-      INTERNAL_SYSCALL_DECL (err);
-      int res;
-
       size_t psize = 128;
-      void *p = alloca (psize);
-
-      while (res = INTERNAL_SYSCALL (sched_getaffinity, err, 3, getpid (),
-				     psize, p),
-	     INTERNAL_SYSCALL_ERROR_P (res, err)
-	     && INTERNAL_SYSCALL_ERRNO (res, err) == EINVAL)
-	p = extend_alloca (p, psize, 2 * psize);
-
-      if (res == 0 || INTERNAL_SYSCALL_ERROR_P (res, err))
+      while (1)
 	{
-	  __set_errno (INTERNAL_SYSCALL_ERRNO (res, err));
-	  return -1;
+	  char buf[psize];
+	  INTERNAL_SYSCALL_DECL (err);
+	  int res = INTERNAL_SYSCALL (sched_getaffinity, err, 3, getpid (),
+				      psize, buf);
+	  if (INTERNAL_SYSCALL_ERROR_P (res, err)
+	      && INTERNAL_SYSCALL_ERRNO (res, err) == EINVAL)
+	    /* Retry with larger size.  */
+	    psize *= 2;
+	  else if (res == 0 || INTERNAL_SYSCALL_ERROR_P (res, err))
+	    {
+	      __set_errno (INTERNAL_SYSCALL_ERRNO (res, err));
+	      return -1;
+	    }
+	  else
+	    {
+	      /* Size has been determined.  */
+	      __kernel_cpumask_size = res;
+	      break;
+	    }
 	}
-
-      __kernel_cpumask_size = res;
     }
 
   /* We now know the size of the kernel cpumask_t.  Make sure the user