From ec08f13dad2a25a407f4aff76b406924c91193ec Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 26 Apr 2007 04:50:57 +0000 Subject: * sysdeps/unix/sysv/linux/bits/sched.h: Declare sched_getcpu. * sysdeps/unix/sysv/linux/sched_getcpu.c: New file. * sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S: New file. * sysdeps/unix/sysv/linux/Versions: Export sched_getcpu for GLIBC_2.6. --- ChangeLog | 8 +++++ nptl/sysdeps/x86_64/tcb-offsets.sym | 1 + sysdeps/unix/sysv/linux/Versions | 2 +- sysdeps/unix/sysv/linux/bits/sched.h | 3 ++ sysdeps/unix/sysv/linux/sched_getcpu.c | 37 ++++++++++++++++++++ sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S | 50 +++++++++++++++++++++++++++ 6 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 sysdeps/unix/sysv/linux/sched_getcpu.c create mode 100644 sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S diff --git a/ChangeLog b/ChangeLog index 4a94ec2e49..baaa4f1041 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-04-25 Ulrich Drepper + + * sysdeps/unix/sysv/linux/bits/sched.h: Declare sched_getcpu. + * sysdeps/unix/sysv/linux/sched_getcpu.c: New file. + * sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S: New file. + * sysdeps/unix/sysv/linux/Versions: Export sched_getcpu for + GLIBC_2.6. + 2007-04-25 Jakub Jelinek * sysdeps/unix/sysv/linux/check_pf.c (make_request): Return -1 instead diff --git a/nptl/sysdeps/x86_64/tcb-offsets.sym b/nptl/sysdeps/x86_64/tcb-offsets.sym index a9ede75c96..21274ecab9 100644 --- a/nptl/sysdeps/x86_64/tcb-offsets.sym +++ b/nptl/sysdeps/x86_64/tcb-offsets.sym @@ -11,3 +11,4 @@ CLEANUP_PREV offsetof (struct _pthread_cleanup_buffer, __prev) MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock) MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) POINTER_GUARD offsetof (tcbhead_t, pointer_guard) +VGETCPU_CACHE_OFFSET offsetof (tcbhead_t, vgetcpu_cache) 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/sched_getcpu.c b/sysdeps/unix/sysv/linux/sched_getcpu.c new file mode 100644 index 0000000000..d0c0132eb9 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sched_getcpu.c @@ -0,0 +1,37 @@ +/* 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 +#include + + +int +sched_getcpu (void) +{ +#ifdef __NR_getcpu + unsigned int cpu; + INTERNAL_SYSCALL_DECL (err); + int r = INTERNAL_SYSCALL (getcpu, err, &cpu, NULL, NULL); + + return (INTERNAL_SYSCALL_ERROR (r, err) + ? INTERNAL_SYSCALL_ERRNO (r, err) : 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 +#include +#define _ERRNO_H 1 +#include + +/* 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) -- cgit v1.2.3