提交 db66ef1f 编写于 作者: N Nathan Zadoks 提交者: Rich Felker

add sched_getcpu vDSO support

This brings the call to an actually usable speed.
Quick unscientific benchmark: 14ns : 102ns :: vDSO : syscall
上级 98d33573
...@@ -64,3 +64,5 @@ static __inline long __syscall6(long n, long a1, long a2, long a3, long a4, long ...@@ -64,3 +64,5 @@ static __inline long __syscall6(long n, long a1, long a2, long a3, long a4, long
#define VDSO_USEFUL #define VDSO_USEFUL
#define VDSO_CGT_SYM "__vdso_clock_gettime" #define VDSO_CGT_SYM "__vdso_clock_gettime"
#define VDSO_CGT_VER "LINUX_2.6" #define VDSO_CGT_VER "LINUX_2.6"
#define VDSO_GETCPU_SYM "__vdso_getcpu"
#define VDSO_GETCPU_VER "LINUX_2.6"
#define _GNU_SOURCE #define _GNU_SOURCE
#include <errno.h>
#include <sched.h> #include <sched.h>
#include "syscall.h" #include "syscall.h"
#include "atomic.h"
#ifdef VDSO_GETCPU_SYM
void *__vdsosym(const char *, const char *);
static void *volatile vdso_func;
typedef long (*getcpu_f)(unsigned *, unsigned *, void *);
static long getcpu_init(unsigned *cpu, unsigned *node, void *unused)
{
void *p = __vdsosym(VDSO_GETCPU_VER, VDSO_GETCPU_SYM);
getcpu_f f = (getcpu_f)p;
a_cas_p(&vdso_func, (void *)getcpu_init, p);
return f ? f(cpu, node, unused) : -ENOSYS;
}
static void *volatile vdso_func = (void *)getcpu_init;
#endif
int sched_getcpu(void) int sched_getcpu(void)
{ {
int r; int r;
unsigned cpu; unsigned cpu;
#ifdef VDSO_GETCPU_SYM
getcpu_f f = (getcpu_f)vdso_func;
if (f) {
r = f(&cpu, 0, 0);
if (!r) return cpu;
if (r != -ENOSYS) return __syscall_ret(r);
}
#endif
r = __syscall(SYS_getcpu, &cpu, 0, 0); r = __syscall(SYS_getcpu, &cpu, 0, 0);
if (!r) return cpu; if (!r) return cpu;
return __syscall_ret(r); return __syscall_ret(r);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册