• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2  * Licensed under the Apache License, Version 2.0 (the "License");
3  * you may not use this file except in compliance with the License.
4  * You may obtain a copy of the License at
5  *
6  *	 http://www.apache.org/licenses/LICENSE-2.0
7  *
8  * Unless required by applicable law or agreed to in writing, software
9  * distributed under the License is distributed on an "AS IS" BASIS,
10  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  * See the License for the specific language governing permissions and
12  * limitations under the License.
13  */
14 
15 #define _GNU_SOURCE
16 #include <errno.h>
17 #include <sched.h>
18 #include "syscall.h"
19 #include "atomic.h"
20 
21 #ifdef VDSO_GETCPU_SYM
22 
23 static void *volatile vdso_func;
24 
25 typedef long (*getcpu_f)(unsigned *, unsigned *, void *);
26 
getcpu_init(unsigned * cpu,unsigned * node,void * unused)27 static long getcpu_init(unsigned *cpu, unsigned *node, void *unused)
28 {
29         __get_vdso_info();
30 	void *p = __get_vdso_addr(VDSO_GETCPU_VER, VDSO_GETCPU_SYM);
31 	getcpu_f f = (getcpu_f)p;
32 	a_cas_p(&vdso_func, (void *)getcpu_init, p);
33 	return f ? f(cpu, node, unused) : -ENOSYS;
34 }
35 
36 static void *volatile vdso_func = (void *)getcpu_init;
37 
38 #endif
39 
sched_getcpu(void)40 int sched_getcpu(void)
41 {
42 	int r;
43 	unsigned cpu;
44 
45 #ifdef VDSO_GETCPU_SYM
46 	getcpu_f f = (getcpu_f)vdso_func;
47 	if (f) {
48 		r = f(&cpu, 0, 0);
49 		if (!r) return cpu;
50 		if (r != -ENOSYS) return __syscall_ret(r);
51 	}
52 #endif
53 
54 	r = __syscall(SYS_getcpu, &cpu, 0, 0);
55 	if (!r) return cpu;
56 	return __syscall_ret(r);
57 }
58