diff options
author | Florian Weimer <fweimer@redhat.com> | 2015-03-23 16:34:48 +0100 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2015-03-23 16:34:48 +0100 |
commit | 98734cc50153c80047f4ed9c6772bc7e1e68c9f7 (patch) | |
tree | e208493e21d45365648a93fa2103d5775b855b91 /sysdeps/unix | |
parent | 2b028564f14d20cdda0c00d8ba100695b40501f5 (diff) | |
download | glibc-98734cc50153c80047f4ed9c6772bc7e1e68c9f7.tar glibc-98734cc50153c80047f4ed9c6772bc7e1e68c9f7.tar.gz glibc-98734cc50153c80047f4ed9c6772bc7e1e68c9f7.tar.bz2 glibc-98734cc50153c80047f4ed9c6772bc7e1e68c9f7.zip |
pthread_setaffinity (Linux variant): Rewrite to use VLA instead of alloca
extend_alloca was used to emulate VLA deallocation. The new version
also handles the res == 0 corner case more explicitly, by returning 0
instead of the (potentially undefined, but usually zero) system call
error.
Diffstat (limited to 'sysdeps/unix')
-rw-r--r-- | sysdeps/unix/sysv/linux/pthread_setaffinity.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/sysdeps/unix/sysv/linux/pthread_setaffinity.c b/sysdeps/unix/sysv/linux/pthread_setaffinity.c index 37997e9688..e891818e8b 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,26 +26,30 @@ 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); + size_t psize; 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); + for (psize = 128; ; psize *= 2) + { + char buf[psize]; + INTERNAL_SYSCALL_DECL (err); + + res = INTERNAL_SYSCALL (sched_getaffinity, err, 3, tid, psize, buf); + if (INTERNAL_SYSCALL_ERROR_P (res, err)) + { + if (INTERNAL_SYSCALL_ERRNO (res, err) != EINVAL) + return INTERNAL_SYSCALL_ERRNO (res, err); + } + else + break; + } - __kernel_cpumask_size = res; + if (res != 0) + __kernel_cpumask_size = res; return 0; } |