Skip to content

Commit 2ef2f9d

Browse files
authored
Merge pull request #2475 from LemonBoy/linux-wo-vdso
Fix clock_gettime on systems without VDSO
2 parents 3d93c89 + 1b23348 commit 2ef2f9d

File tree

1 file changed

+27
-13
lines changed

1 file changed

+27
-13
lines changed

std/os/linux.zig

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

962+
var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime);
963+
962964
pub 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
}
975-
var vdso_clock_gettime = init_vdso_clock_gettime;
978+
976979
extern 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

984992
pub 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
11041112

11051113
const NSIG = 65;
11061114
const sigset_t = [128 / @sizeOf(usize)]usize;
1107-
const all_mask = []u32{0xffffffff, 0xffffffff};
1108-
const app_mask = []u32{0xfffffffc, 0x7fffffff};
1115+
const all_mask = []u32{ 0xffffffff, 0xffffffff };
1116+
const app_mask = []u32{ 0xfffffffc, 0x7fffffff };
11091117

11101118
const k_sigaction = extern struct {
11111119
handler: extern fn (i32) void,
@@ -1403,9 +1411,15 @@ pub const epoll_data = extern union {
14031411
// On x86_64 the structure is packed so that it matches the definition of its
14041412
// 32bit counterpart
14051413
pub const epoll_event = if (builtin.arch != .x86_64)
1406-
extern struct { events: u32, data: epoll_data }
1407-
else
1408-
packed struct { events: u32, data: epoll_data };
1414+
extern struct {
1415+
events: u32,
1416+
data: epoll_data,
1417+
}
1418+
else
1419+
packed struct {
1420+
events: u32,
1421+
data: epoll_data,
1422+
};
14091423

14101424
pub fn epoll_create() usize {
14111425
return epoll_create1(0);

0 commit comments

Comments
 (0)