authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-11 12:01:52-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-05-11 12:01:52-04:00
log2ef2f9d71f851823966ae16b45a189657051b8df
tree9d6f1c17e04869fe105023dbfa09c5af7c518273
parent3d93c89fc55a428171bbfa779fb604801d84421d
parent1b23348f30243ed61a61f1892bb391d8afab7f10
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #2475 from LemonBoy/linux-wo-vdso

Fix clock_gettime on systems without VDSO

1 files changed, 27 insertions(+), 13 deletions(-)

std/os/linux.zig+27-13
...@@ -959,10 +959,13 @@ pub fn waitpid(pid: i32, status: *i32, options: i32) usize {...@@ -959,10 +959,13 @@ pub fn waitpid(pid: i32, status: *i32, options: i32) usize {
959 return syscall4(SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), @bitCast(usize, isize(options)), 0);959 return syscall4(SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), @bitCast(usize, isize(options)), 0);
960}960}
961961
962var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime);
963
962pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {964pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
963 if (VDSO_CGT_SYM.len != 0) {965 if (VDSO_CGT_SYM.len != 0) {
964 const f = @atomicLoad(@typeOf(init_vdso_clock_gettime), &vdso_clock_gettime, builtin.AtomicOrder.Unordered);966 const ptr = @atomicLoad(?*const c_void, &vdso_clock_gettime, .Unordered);
965 if (@ptrToInt(f) != 0) {967 if (ptr) |fn_ptr| {
968 const f = @ptrCast(@typeOf(clock_gettime), fn_ptr);
966 const rc = f(clk_id, tp);969 const rc = f(clk_id, tp);
967 switch (rc) {970 switch (rc) {
968 0, @bitCast(usize, isize(-EINVAL)) => return rc,971 0, @bitCast(usize, isize(-EINVAL)) => return rc,
...@@ -972,13 +975,18 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {...@@ -972,13 +975,18 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
972 }975 }
973 return syscall2(SYS_clock_gettime, @bitCast(usize, isize(clk_id)), @ptrToInt(tp));976 return syscall2(SYS_clock_gettime, @bitCast(usize, isize(clk_id)), @ptrToInt(tp));
974}977}
975var vdso_clock_gettime = init_vdso_clock_gettime;978
976extern fn init_vdso_clock_gettime(clk: i32, ts: *timespec) usize {979extern fn init_vdso_clock_gettime(clk: i32, ts: *timespec) usize {
977 const addr = vdso.lookup(VDSO_CGT_VER, VDSO_CGT_SYM);980 const ptr = @intToPtr(?*const c_void, vdso.lookup(VDSO_CGT_VER, VDSO_CGT_SYM));
978 var f = @intToPtr(@typeOf(init_vdso_clock_gettime), addr);981 // Note that we may not have a VDSO at all, update the stub address anyway
979 _ = @cmpxchgStrong(@typeOf(init_vdso_clock_gettime), &vdso_clock_gettime, init_vdso_clock_gettime, f, builtin.AtomicOrder.Monotonic, builtin.AtomicOrder.Monotonic);982 // so that clock_gettime will fall back on the good old (and slow) syscall
980 if (@ptrToInt(f) == 0) return @bitCast(usize, isize(-ENOSYS));983 _ = @cmpxchgStrong(?*const c_void, &vdso_clock_gettime, &init_vdso_clock_gettime, ptr, .Monotonic, .Monotonic);
981 return f(clk, ts);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));
982}990}
983991
984pub fn clock_getres(clk_id: i32, tp: *timespec) usize {992pub fn clock_getres(clk_id: i32, tp: *timespec) usize {
...@@ -1104,8 +1112,8 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti...@@ -1104,8 +1112,8 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti
11041112
1105const NSIG = 65;1113const NSIG = 65;
1106const sigset_t = [128 / @sizeOf(usize)]usize;1114const sigset_t = [128 / @sizeOf(usize)]usize;
1107const all_mask = []u32{0xffffffff, 0xffffffff};1115const all_mask = []u32{ 0xffffffff, 0xffffffff };
1108const app_mask = []u32{0xfffffffc, 0x7fffffff};1116const app_mask = []u32{ 0xfffffffc, 0x7fffffff };
11091117
1110const k_sigaction = extern struct {1118const k_sigaction = extern struct {
1111 handler: extern fn (i32) void,1119 handler: extern fn (i32) void,
...@@ -1403,9 +1411,15 @@ pub const epoll_data = extern union {...@@ -1403,9 +1411,15 @@ pub const epoll_data = extern union {
1403// On x86_64 the structure is packed so that it matches the definition of its1411// On x86_64 the structure is packed so that it matches the definition of its
1404// 32bit counterpart1412// 32bit counterpart
1405pub const epoll_event = if (builtin.arch != .x86_64)1413pub const epoll_event = if (builtin.arch != .x86_64)
1406 extern struct { events: u32, data: epoll_data }1414 extern struct {
1407 else1415 events: u32,
1408 packed struct { events: u32, data: epoll_data };1416 data: epoll_data,
1417 }
1418else
1419 packed struct {
1420 events: u32,
1421 data: epoll_data,
1422 };
14091423
1410pub fn epoll_create() usize {1424pub fn epoll_create() usize {
1411 return epoll_create1(0);1425 return epoll_create1(0);