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

Fix clock_gettime on systems without VDSO
This commit is contained in:
Andrew Kelley 2019-05-11 12:01:52 -04:00 committed by GitHub
commit 2ef2f9d71f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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 {
@ -1104,8 +1112,8 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti
const NSIG = 65; const NSIG = 65;
const sigset_t = [128 / @sizeOf(usize)]usize; const sigset_t = [128 / @sizeOf(usize)]usize;
const all_mask = []u32{0xffffffff, 0xffffffff}; const all_mask = []u32{ 0xffffffff, 0xffffffff };
const app_mask = []u32{0xfffffffc, 0x7fffffff}; const app_mask = []u32{ 0xfffffffc, 0x7fffffff };
const k_sigaction = extern struct { const k_sigaction = extern struct {
handler: extern fn (i32) void, handler: extern fn (i32) void,
@ -1403,9 +1411,15 @@ pub const epoll_data = extern union {
// On x86_64 the structure is packed so that it matches the definition of its // On x86_64 the structure is packed so that it matches the definition of its
// 32bit counterpart // 32bit counterpart
pub const epoll_event = if (builtin.arch != .x86_64) pub const epoll_event = if (builtin.arch != .x86_64)
extern struct { events: u32, data: epoll_data } extern struct {
else events: u32,
packed struct { events: u32, data: epoll_data }; data: epoll_data,
}
else
packed struct {
events: u32,
data: epoll_data,
};
pub fn epoll_create() usize { pub fn epoll_create() usize {
return epoll_create1(0); return epoll_create1(0);