This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH 02/25] pthread_setaffinity (Linux variant): Rewrite to use VLA instead of alloca
- From: Florian Weimer <fweimer at redhat dot com>
- To: libc-alpha at sourceware dot org
- Date: Sun, 1 Mar 2015 15:05:09 +0100
- Subject: [PATCH 02/25] pthread_setaffinity (Linux variant): Rewrite to use VLA instead of alloca
- Authentication-results: sourceware.org; auth=none
- References: <cover dot 1425285061 dot git dot fweimer at redhat dot com>
extend_alloca was used to emulate VLA deallocation.
---
sysdeps/unix/sysv/linux/pthread_setaffinity.c | 37 ++++++++++++++-------------
1 file changed, 19 insertions(+), 18 deletions(-)
diff --git a/sysdeps/unix/sysv/linux/pthread_setaffinity.c b/sysdeps/unix/sysv/linux/pthread_setaffinity.c
index 37997e9..69a9a37 100644
--- a/sysdeps/unix/sysv/linux/pthread_setaffinity.c
+++ b/sysdeps/unix/sysv/linux/pthread_setaffinity.c
@@ -16,7 +16,6 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <alloca.h>
#include <errno.h>
#include <pthreadP.h>
#include <sysdep.h>
@@ -27,27 +26,29 @@
size_t __kernel_cpumask_size attribute_hidden;
-/* Determine the current affinity. As a side affect we learn
- about the size of the cpumask_t in the kernel. */
+/* Determine the size of cpumask_t in the kernel. */
int
__determine_cpumask_size (pid_t tid)
{
- INTERNAL_SYSCALL_DECL (err);
- int res;
-
size_t psize = 128;
- void *p = alloca (psize);
-
- while (res = INTERNAL_SYSCALL (sched_getaffinity, err, 3, tid, 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))
- return INTERNAL_SYSCALL_ERRNO (res, err);
-
- __kernel_cpumask_size = res;
-
+ while (1)
+ {
+ char buf[psize];
+ INTERNAL_SYSCALL_DECL (err);
+ int res = INTERNAL_SYSCALL (sched_getaffinity, err, 3, tid, 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))
+ return INTERNAL_SYSCALL_ERRNO (res, err);
+ else
+ {
+ /* Size has been determined. */
+ __kernel_cpumask_size = res;
+ break;
+ }
+ }
return 0;
}
--
2.1.0