github.com/afumu/libc@v0.0.6/musl/src/sched/sched_getcpu.c (about)

     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  }