diff options
Diffstat (limited to 'libc-top-half/musl/src/sched/sched_getcpu.c')
-rw-r--r-- | libc-top-half/musl/src/sched/sched_getcpu.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/libc-top-half/musl/src/sched/sched_getcpu.c b/libc-top-half/musl/src/sched/sched_getcpu.c new file mode 100644 index 0000000..4ec5eaf --- /dev/null +++ b/libc-top-half/musl/src/sched/sched_getcpu.c @@ -0,0 +1,42 @@ +#define _GNU_SOURCE +#include <errno.h> +#include <sched.h> +#include "syscall.h" +#include "atomic.h" + +#ifdef VDSO_GETCPU_SYM + +static void *volatile vdso_func; + +typedef long (*getcpu_f)(unsigned *, unsigned *, void *); + +static long getcpu_init(unsigned *cpu, unsigned *node, void *unused) +{ + void *p = __vdsosym(VDSO_GETCPU_VER, VDSO_GETCPU_SYM); + getcpu_f f = (getcpu_f)p; + a_cas_p(&vdso_func, (void *)getcpu_init, p); + return f ? f(cpu, node, unused) : -ENOSYS; +} + +static void *volatile vdso_func = (void *)getcpu_init; + +#endif + +int sched_getcpu(void) +{ + int r; + unsigned cpu; + +#ifdef VDSO_GETCPU_SYM + getcpu_f f = (getcpu_f)vdso_func; + if (f) { + r = f(&cpu, 0, 0); + if (!r) return cpu; + if (r != -ENOSYS) return __syscall_ret(r); + } +#endif + + r = __syscall(SYS_getcpu, &cpu, 0, 0); + if (!r) return cpu; + return __syscall_ret(r); +} |