sched_getcpu.c raw

   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