handle mremap failure in realloc of mmap-serviced allocations
[musl] / src / sched / sched_getcpu.c
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 void *__vdsosym(const char *, const char *);
10
11 static void *volatile vdso_func;
12
13 typedef long (*getcpu_f)(unsigned *, unsigned *, void *);
14
15 static long getcpu_init(unsigned *cpu, unsigned *node, void *unused)
16 {
17         void *p = __vdsosym(VDSO_GETCPU_VER, VDSO_GETCPU_SYM);
18         getcpu_f f = (getcpu_f)p;
19         a_cas_p(&vdso_func, (void *)getcpu_init, p);
20         return f ? f(cpu, node, unused) : -ENOSYS;
21 }
22
23 static void *volatile vdso_func = (void *)getcpu_init;
24
25 #endif
26
27 int sched_getcpu(void)
28 {
29         int r;
30         unsigned cpu;
31
32 #ifdef VDSO_GETCPU_SYM
33         getcpu_f f = (getcpu_f)vdso_func;
34         if (f) {
35                 r = f(&cpu, 0, 0);
36                 if (!r) return cpu;
37                 if (r != -ENOSYS) return __syscall_ret(r);
38         }
39 #endif
40
41         r = __syscall(SYS_getcpu, &cpu, 0, 0);
42         if (!r) return cpu;
43         return __syscall_ret(r);
44 }