Linux: Use rseq in sched_getcpu if available

When available, use the cpu_id field from __rseq_abi on Linux to
implement sched_getcpu().  Fall-back on the vgetcpu vDSO if unavailable.

Benchmarks:

x86-64: Intel E5-2630 v3@2.40GHz, 16-core, hyperthreading

glibc sched_getcpu():                     13.7 ns (baseline)
glibc sched_getcpu() using rseq:           2.5 ns (speedup:  5.5x)
inline load cpuid from __rseq_abi TLS:     0.8 ns (speedup: 17.1x)
This commit is contained in:
Mathieu Desnoyers 2020-07-06 10:21:31 +02:00 committed by Florian Weimer
parent 0c76fc3c2b
commit 6e29cb3f61

View File

@ -18,10 +18,12 @@
#include <errno.h> #include <errno.h>
#include <sched.h> #include <sched.h>
#include <sysdep.h> #include <sysdep.h>
#include <atomic.h>
#include <sysdep-vdso.h> #include <sysdep-vdso.h>
#include <sys/rseq.h>
int static int
sched_getcpu (void) vsyscall_sched_getcpu (void)
{ {
unsigned int cpu; unsigned int cpu;
int r = -1; int r = -1;
@ -32,3 +34,19 @@ sched_getcpu (void)
#endif #endif
return r == -1 ? r : cpu; return r == -1 ? r : cpu;
} }
#ifdef RSEQ_SIG
int
sched_getcpu (void)
{
int cpu_id = atomic_load_relaxed (&__rseq_abi.cpu_id);
return cpu_id >= 0 ? cpu_id : vsyscall_sched_getcpu ();
}
#else /* RSEQ_SIG */
int
sched_getcpu (void)
{
return vsyscall_sched_getcpu ();
}
#endif /* RSEQ_SIG */