linux: Fix clock_gettime on systems w/o VDSO
parent
d065f297ab
commit
715d808f14
|
@ -959,10 +959,13 @@ pub fn waitpid(pid: i32, status: *i32, options: i32) usize {
|
||||||
return syscall4(SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), @bitCast(usize, isize(options)), 0);
|
return syscall4(SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), @bitCast(usize, isize(options)), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime);
|
||||||
|
|
||||||
pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
|
pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
|
||||||
if (VDSO_CGT_SYM.len != 0) {
|
if (VDSO_CGT_SYM.len != 0) {
|
||||||
const f = @atomicLoad(@typeOf(init_vdso_clock_gettime), &vdso_clock_gettime, builtin.AtomicOrder.Unordered);
|
const ptr = @atomicLoad(?*const c_void, &vdso_clock_gettime, .Unordered);
|
||||||
if (@ptrToInt(f) != 0) {
|
if (ptr) |fn_ptr| {
|
||||||
|
const f = @ptrCast(@typeOf(clock_gettime), fn_ptr);
|
||||||
const rc = f(clk_id, tp);
|
const rc = f(clk_id, tp);
|
||||||
switch (rc) {
|
switch (rc) {
|
||||||
0, @bitCast(usize, isize(-EINVAL)) => return rc,
|
0, @bitCast(usize, isize(-EINVAL)) => return rc,
|
||||||
|
@ -972,13 +975,18 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
|
||||||
}
|
}
|
||||||
return syscall2(SYS_clock_gettime, @bitCast(usize, isize(clk_id)), @ptrToInt(tp));
|
return syscall2(SYS_clock_gettime, @bitCast(usize, isize(clk_id)), @ptrToInt(tp));
|
||||||
}
|
}
|
||||||
var vdso_clock_gettime = init_vdso_clock_gettime;
|
|
||||||
extern fn init_vdso_clock_gettime(clk: i32, ts: *timespec) usize {
|
extern fn init_vdso_clock_gettime(clk: i32, ts: *timespec) usize {
|
||||||
const addr = vdso.lookup(VDSO_CGT_VER, VDSO_CGT_SYM);
|
const ptr = @intToPtr(?*const c_void, vdso.lookup(VDSO_CGT_VER, VDSO_CGT_SYM));
|
||||||
var f = @intToPtr(@typeOf(init_vdso_clock_gettime), addr);
|
// Note that we may not have a VDSO at all, update the stub address anyway
|
||||||
_ = @cmpxchgStrong(@typeOf(init_vdso_clock_gettime), &vdso_clock_gettime, init_vdso_clock_gettime, f, builtin.AtomicOrder.Monotonic, builtin.AtomicOrder.Monotonic);
|
// so that clock_gettime will fall back on the good old (and slow) syscall
|
||||||
if (@ptrToInt(f) == 0) return @bitCast(usize, isize(-ENOSYS));
|
_ = @cmpxchgStrong(?*const c_void, &vdso_clock_gettime, &init_vdso_clock_gettime, ptr, .Monotonic, .Monotonic);
|
||||||
return f(clk, ts);
|
// Call into the VDSO if available
|
||||||
|
if (ptr) |fn_ptr| {
|
||||||
|
const f = @ptrCast(@typeOf(clock_gettime), fn_ptr);
|
||||||
|
return f(clk, ts);
|
||||||
|
}
|
||||||
|
return @bitCast(usize, isize(-ENOSYS));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clock_getres(clk_id: i32, tp: *timespec) usize {
|
pub fn clock_getres(clk_id: i32, tp: *timespec) usize {
|
||||||
|
|
Loading…
Reference in New Issue