authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-05-11 10:33:41+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-05-11 10:33:41+02:00
log715d808f14e132df9eb4e29261d010eca5cfb82a
tree8d4e2695e0878c8e68b2c865160f95c22ee08c20
parentd065f297ab6de5ca35636d169195ce5da6235786

linux: Fix clock_gettime on systems w/o VDSO


1 files changed, 16 insertions(+), 8 deletions(-)

std/os/linux.zig+16-8
......@@ -959,10 +959,13 @@ pub fn waitpid(pid: i32, status: *i32, options: i32) usize {
959959 return syscall4(SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), @bitCast(usize, isize(options)), 0);
960960}
961961
962var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime);
963
962964pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
963965 if (VDSO_CGT_SYM.len != 0) {
964 const f = @atomicLoad(@typeOf(init_vdso_clock_gettime), &vdso_clock_gettime, builtin.AtomicOrder.Unordered);
965 if (@ptrToInt(f) != 0) {
966 const ptr = @atomicLoad(?*const c_void, &vdso_clock_gettime, .Unordered);
967 if (ptr) |fn_ptr| {
968 const f = @ptrCast(@typeOf(clock_gettime), fn_ptr);
966969 const rc = f(clk_id, tp);
967970 switch (rc) {
968971 0, @bitCast(usize, isize(-EINVAL)) => return rc,
......@@ -972,13 +975,18 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
972975 }
973976 return syscall2(SYS_clock_gettime, @bitCast(usize, isize(clk_id)), @ptrToInt(tp));
974977}
975var vdso_clock_gettime = init_vdso_clock_gettime;
978
976979extern fn init_vdso_clock_gettime(clk: i32, ts: *timespec) usize {
977 const addr = vdso.lookup(VDSO_CGT_VER, VDSO_CGT_SYM);
978 var f = @intToPtr(@typeOf(init_vdso_clock_gettime), addr);
979 _ = @cmpxchgStrong(@typeOf(init_vdso_clock_gettime), &vdso_clock_gettime, init_vdso_clock_gettime, f, builtin.AtomicOrder.Monotonic, builtin.AtomicOrder.Monotonic);
980 if (@ptrToInt(f) == 0) return @bitCast(usize, isize(-ENOSYS));
981 return f(clk, ts);
980 const ptr = @intToPtr(?*const c_void, vdso.lookup(VDSO_CGT_VER, VDSO_CGT_SYM));
981 // Note that we may not have a VDSO at all, update the stub address anyway
982 // so that clock_gettime will fall back on the good old (and slow) syscall
983 _ = @cmpxchgStrong(?*const c_void, &vdso_clock_gettime, &init_vdso_clock_gettime, ptr, .Monotonic, .Monotonic);
984 // Call into the VDSO if available
985 if (ptr) |fn_ptr| {
986 const f = @ptrCast(@typeOf(clock_gettime), fn_ptr);
987 return f(clk, ts);
988 }
989 return @bitCast(usize, isize(-ENOSYS));
982990}
983991
984992pub fn clock_getres(clk_id: i32, tp: *timespec) usize {