xref: /third_party/musl/src/sched/sched_getcpu.c (revision 570af302)
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
9static void *volatile vdso_func;
10
11typedef long (*getcpu_f)(unsigned *, unsigned *, void *);
12
13static long getcpu_init(unsigned *cpu, unsigned *node, void *unused)
14{
15#ifndef __LITEOS__
16	__get_vdso_info();
17	void *p = __get_vdso_addr(VDSO_GETCPU_VER, VDSO_GETCPU_SYM);
18#else
19	void *p = __vdsosym(VDSO_GETCPU_VER, VDSO_GETCPU_SYM);
20#endif
21	getcpu_f f = (getcpu_f)p;
22	a_cas_p(&vdso_func, (void *)getcpu_init, p);
23	return f ? f(cpu, node, unused) : -ENOSYS;
24}
25
26static void *volatile vdso_func = (void *)getcpu_init;
27
28#endif
29
30int sched_getcpu(void)
31{
32	int r;
33	unsigned cpu;
34
35#ifdef VDSO_GETCPU_SYM
36	getcpu_f f = (getcpu_f)vdso_func;
37	if (f) {
38		r = f(&cpu, 0, 0);
39		if (!r) return cpu;
40		if (r != -ENOSYS) return __syscall_ret(r);
41	}
42#endif
43
44	r = __syscall(SYS_getcpu, &cpu, 0, 0);
45	if (!r) return cpu;
46	return __syscall_ret(r);
47}
48