Message ID | 20240206162801.882585-9-mjeanson@efficios.com |
---|---|
State | New |
Headers | show |
Series | Extend rseq support | expand |
Michael Jeanson <mjeanson@efficios.com> writes: > diff --git a/sysdeps/unix/sysv/linux/getcpu.c b/sysdeps/unix/sysv/linux/getcpu.c > index 0e7c3238c9..7e34d6d1eb 100644 > --- a/sysdeps/unix/sysv/linux/getcpu.c > +++ b/sysdeps/unix/sysv/linux/getcpu.c > @@ -19,9 +19,10 @@ > #include <sched.h> > #include <sysdep.h> > #include <sysdep-vdso.h> > +#include <rseq-internal.h> > > -int > -__getcpu (unsigned int *cpu, unsigned int *node) > +static int > +vsyscall_getcpu (unsigned int *cpu, unsigned int *node) Ok; this is the original function. Any reason (other than "cleaner diffs") to have this separate, and not just make it the #else clause below? Ah, it's called twice below. Got it. Ok. Do we want to tag this as always inline for the better CPU performance? > @@ -29,5 +30,32 @@ __getcpu (unsigned int *cpu, unsigned int *node) > +#if defined (RSEQ_SIG) && defined (RSEQ_HAS_LOAD32_LOAD32_RELAXED) > +int > +__getcpu (unsigned int *cpu, unsigned int *node) > +{ > + /* Check if rseq is registered and the node_id feature is available. */ > + if (__glibc_likely (rseq_node_id_available())) > + { > + struct rseq_area *rseq_area = rseq_get_area(); > + > + if (rseq_load32_load32_relaxed(cpu, &rseq_area->cpu_id, > + node, &rseq_area->node_id) == 0) > + { > + /* The critical section was not aborted, return 0. */ > + return 0; > + } > + } > + > + return vsyscall_getcpu (cpu, node); > +} > +#else > +int > +__getcpu (unsigned int *cpu, unsigned int *node) > +{ > + return vsyscall_getcpu (cpu, node); > +} > +#endif > weak_alias (__getcpu, getcpu) > libc_hidden_def (__getcpu) Ok.
On 2024-02-16 22:57, DJ Delorie wrote: > Michael Jeanson <mjeanson@efficios.com> writes: >> diff --git a/sysdeps/unix/sysv/linux/getcpu.c b/sysdeps/unix/sysv/linux/getcpu.c >> index 0e7c3238c9..7e34d6d1eb 100644 >> --- a/sysdeps/unix/sysv/linux/getcpu.c >> +++ b/sysdeps/unix/sysv/linux/getcpu.c >> @@ -19,9 +19,10 @@ >> #include <sched.h> >> #include <sysdep.h> >> #include <sysdep-vdso.h> >> +#include <rseq-internal.h> >> >> -int >> -__getcpu (unsigned int *cpu, unsigned int *node) >> +static int >> +vsyscall_getcpu (unsigned int *cpu, unsigned int *node) > > Ok; this is the original function. Any reason (other than "cleaner > diffs") to have this separate, and not just make it the #else clause > below? > > Ah, it's called twice below. Got it. Ok. Do we want to tag this as > always inline for the better CPU performance? Yes, will do.
diff --git a/sysdeps/unix/sysv/linux/getcpu.c b/sysdeps/unix/sysv/linux/getcpu.c index 0e7c3238c9..7e34d6d1eb 100644 --- a/sysdeps/unix/sysv/linux/getcpu.c +++ b/sysdeps/unix/sysv/linux/getcpu.c @@ -19,9 +19,10 @@ #include <sched.h> #include <sysdep.h> #include <sysdep-vdso.h> +#include <rseq-internal.h> -int -__getcpu (unsigned int *cpu, unsigned int *node) +static int +vsyscall_getcpu (unsigned int *cpu, unsigned int *node) { #ifdef HAVE_GETCPU_VSYSCALL return INLINE_VSYSCALL (getcpu, 3, cpu, node, NULL); @@ -29,5 +30,32 @@ __getcpu (unsigned int *cpu, unsigned int *node) return INLINE_SYSCALL_CALL (getcpu, cpu, node, NULL); #endif } + +#if defined (RSEQ_SIG) && defined (RSEQ_HAS_LOAD32_LOAD32_RELAXED) +int +__getcpu (unsigned int *cpu, unsigned int *node) +{ + /* Check if rseq is registered and the node_id feature is available. */ + if (__glibc_likely (rseq_node_id_available())) + { + struct rseq_area *rseq_area = rseq_get_area(); + + if (rseq_load32_load32_relaxed(cpu, &rseq_area->cpu_id, + node, &rseq_area->node_id) == 0) + { + /* The critical section was not aborted, return 0. */ + return 0; + } + } + + return vsyscall_getcpu (cpu, node); +} +#else +int +__getcpu (unsigned int *cpu, unsigned int *node) +{ + return vsyscall_getcpu (cpu, node); +} +#endif weak_alias (__getcpu, getcpu) libc_hidden_def (__getcpu)