diff options
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r-- | sysdeps/unix/sysv/linux/Makefile | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/Versions | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/bits/sched.h | 3 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/check_pf.c | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sched_getcpu.c | 36 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S | 50 |
6 files changed, 92 insertions, 3 deletions
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 1d9443a5fe..78553b9795 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -112,7 +112,7 @@ endif ifeq ($(subdir),posix) sysdep_headers += bits/initspin.h -sysdep_routines += exit-thread +sysdep_routines += exit-thread sched_getcpu endif ifeq ($(subdir),inet) diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index bb5b862689..5413ced74c 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -127,7 +127,7 @@ libc { splice; tee; vmsplice; } GLIBC_2.6 { - epoll_pwait; sync_file_range; + epoll_pwait; sync_file_range; sched_getcpu; } GLIBC_PRIVATE { # functions used in other libraries diff --git a/sysdeps/unix/sysv/linux/bits/sched.h b/sysdeps/unix/sysv/linux/bits/sched.h index 1d9c7b9f35..31db66f8ac 100644 --- a/sysdeps/unix/sysv/linux/bits/sched.h +++ b/sysdeps/unix/sysv/linux/bits/sched.h @@ -77,6 +77,9 @@ extern int clone (int (*__fn) (void *__arg), void *__child_stack, /* Unshare the specified resources. */ extern int unshare (int __flags) __THROW; + +/* Get index of currently used CPU. */ +extern int sched_getcpu (void) __THROW; #endif __END_DECLS diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c index 2b6c158226..3312da3af8 100644 --- a/sysdeps/unix/sysv/linux/check_pf.c +++ b/sysdeps/unix/sysv/linux/check_pf.c @@ -223,7 +223,7 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6, out_fail: if (use_malloc) free (buf); - return 0; + return -1; } diff --git a/sysdeps/unix/sysv/linux/sched_getcpu.c b/sysdeps/unix/sysv/linux/sched_getcpu.c new file mode 100644 index 0000000000..e41eee6431 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sched_getcpu.c @@ -0,0 +1,36 @@ +/* Copyright (C) 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <sched.h> +#include <sysdep.h> + + +int +sched_getcpu (void) +{ +#ifdef __NR_getcpu + unsigned int cpu; + int r = INLINE_SYSCALL (getcpu, 3, &cpu, NULL, NULL); + + return r == -1 ? r : cpu; +#else + __set_errno (ENOSYS); + return -1; +#endif +} diff --git a/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S b/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S new file mode 100644 index 0000000000..8d74d53a76 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S @@ -0,0 +1,50 @@ +/* Copyright (C) 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> +#include <tls.h> +#define _ERRNO_H 1 +#include <bits/errno.h> + +/* For the calculation see asm/vsyscall.h. */ +#define VSYSCALL_ADDR_vgetcpu 0xffffffffff600800 + + +ENTRY (sched_getcpu) + /* Align stack and create local variable for result. */ + sub $0x8, %rsp + cfi_adjust_cfa_offset(8) + + movq %rsp, %rdi + xorl %esi, %esi + movl $VGETCPU_CACHE_OFFSET, %edx + addq %fs:0, %rdx + + movq $VSYSCALL_ADDR_vgetcpu, %rax + callq *%rax + + cmpq $-4095, %rdi + jae SYSCALL_ERROR_LABEL + + movl (%rsp), %eax + +L(pseudo_end): + add $0x8, %rsp + cfi_adjust_cfa_offset(-8) + ret +PSEUDO_END(sched_getcpu) |