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

Message ID 55071AB8.10505@redhat.com
State Deferred
Delegated to: Florian Weimer
Headers

Commit Message

Florian Weimer March 16, 2015, 6:02 p.m. UTC
  On 03/01/2015 03:05 PM, Florian Weimer wrote:
> extend_alloca was used to emulate VLA deallocation.

This new version of the patch follows the changes to the patch
“pthread_setaffinity (Linux variant): Rewrite to use VLA instead of
alloca” (same thread).

2015-03-16  Florian Weimer  <fweimer@redhat.com>

	* sysdeps/unix/sysv/linux/sched_setaffinity.c
	(__sched_setaffinity_new): Replace extend_alloca with a
	variable-length array.  Do not treat res == 0 as an error.
  

Patch

From 2db0ecba2b3d71adfb0fe1620bfb1658901aff10 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Sun, 1 Mar 2015 15:05:41 +0100
Subject: [PATCH] sched_setaffinity (Linux variant): Rewrite to use VLA instead
 of alloca

extend_alloca was used to emulate VLA deallocation.  In addition,
the system call error code from sched_getaffinity is no longer used
if there is no error.
---
 sysdeps/unix/sysv/linux/sched_setaffinity.c | 34 ++++++++++++++++-------------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/sched_setaffinity.c b/sysdeps/unix/sysv/linux/sched_setaffinity.c
index b528617..494ab52 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,30 @@  __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);
+      size_t psize;
       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))
+      for (psize = 128; ; psize *= 2)
 	{
-	  __set_errno (INTERNAL_SYSCALL_ERRNO (res, err));
-	  return -1;
+	  char buf[psize];
+	  INTERNAL_SYSCALL_DECL (err);
+
+	  res = INTERNAL_SYSCALL (sched_getaffinity, err, 3, getpid (),
+				  psize, buf);
+	  if (INTERNAL_SYSCALL_ERROR_P (res, err))
+	    {
+	      if (INTERNAL_SYSCALL_ERRNO (res, err) != EINVAL)
+		{
+		  __set_errno (INTERNAL_SYSCALL_ERRNO (res, err));
+		  return -1;
+		}
+	    }
+	  else
+	    break;
 	}
 
-      __kernel_cpumask_size = res;
+      if (res > 0)
+	__kernel_cpumask_size = res;
     }
 
   /* We now know the size of the kernel cpumask_t.  Make sure the user
-- 
2.1.0