1 | #define _GNU_SOURCE |
2 | #include <errno.h> |
3 | #include <sched.h> |
4 | #include "syscall.h" |
5 | #include "atomic.h" |
6 | |
7 | #ifdef VDSO_GETCPU_SYM |
8 | |
9 | static void *volatile vdso_func; |
10 | |
11 | typedef long (*getcpu_f)(unsigned *, unsigned *, void *); |
12 | |
13 | static long getcpu_init(unsigned *cpu, unsigned *node, void *unused) |
14 | { |
15 | void *p = __vdsosym(VDSO_GETCPU_VER, VDSO_GETCPU_SYM); |
16 | getcpu_f f = (getcpu_f)p; |
17 | a_cas_p(&vdso_func, (void *)getcpu_init, p); |
18 | return f ? f(cpu, node, unused) : -ENOSYS; |
19 | } |
20 | |
21 | static void *volatile vdso_func = (void *)getcpu_init; |
22 | |
23 | #endif |
24 | |
25 | int sched_getcpu(void) |
26 | { |
27 | int r; |
28 | unsigned cpu; |
29 | |
30 | #ifdef VDSO_GETCPU_SYM |
31 | getcpu_f f = (getcpu_f)vdso_func; |
32 | if (f) { |
33 | r = f(&cpu, 0, 0); |
34 | if (!r) return cpu; |
35 | if (r != -ENOSYS) return __syscall_ret(r); |
36 | } |
37 | #endif |
38 | |
39 | r = __syscall(SYS_getcpu, &cpu, 0, 0); |
40 | if (!r) return cpu; |
41 | return __syscall_ret(r); |
42 | } |
43 | |