Skip to content

Commit 360c63c

Browse files
Zentriktopolarityvchuravy
authored
Add fastpath for prctl and add fallback instead of erroring (#43)
Co-authored-by: Zentrik <[email protected]> Co-authored-by: Cody Tapscott <[email protected]> Co-authored-by: Valentin Churavy <[email protected]>
1 parent d4e0a9a commit 360c63c

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

src/LinuxPerf.jl

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -352,18 +352,28 @@ end
352352
const PR_TASK_PERF_EVENTS_DISABLE = Cint(31)
353353
const PR_TASK_PERF_EVENTS_ENABLE = Cint(32)
354354

355-
# syscall is lower overhead than calling libc's prctl
356-
function enable_all!()
357-
SYS_prctl == -1 && error("prctl error : unknown architecture")
358-
res = ccall(:syscall, Cint, (Clong, Clong...), SYS_prctl, PR_TASK_PERF_EVENTS_ENABLE)
359-
Base.systemerror(:prctl, res < 0)
360-
end
361-
function disable_all!()
362-
SYS_prctl == -1 && error("prctl error : unknown architecture")
363-
res = ccall(:syscall, Cint, (Clong, Clong...), SYS_prctl, PR_TASK_PERF_EVENTS_DISABLE)
364-
Base.systemerror(:prctl, res < 0)
355+
@inline function prctl(op)
356+
if SYS_prctl == -1
357+
res = ccall(:prctl, Cint, (Cint, Cint...), op)
358+
return Base.systemerror(:prctl, res < 0)
359+
elseif Sys.ARCH == :x86_64
360+
res = Base.llvmcall("""%val = call i64 asm sideeffect "syscall", "={rax},{rax},{rdi},~{rcx},~{r11},~{memory}"(i64 %0, i64 %1)
361+
ret i64 %val""", Int64, Tuple{Int64, Int64}, SYS_prctl, Int64(op))
362+
return (res >= 0) ? nothing : throw(Base.SystemError("prctl", -res, nothing))
363+
elseif Sys.ARCH == :aarch64
364+
res = Base.llvmcall("""%val = call i64 asm sideeffect "svc #0", "={x0},{x8},{x0},~{memory}"(i64 %0, i64 %1)
365+
ret i64 %val""", Int64, Tuple{Int64, Int64}, SYS_prctl, Int64(op))
366+
return (res >= 0) ? nothing : throw(Base.SystemError("prctl", -res, nothing))
367+
else
368+
# syscall is lower overhead than calling libc's prctl
369+
res = ccall(:syscall, Cint, (Clong, Clong...), SYS_prctl, op)
370+
return Base.systemerror(:prctl, res < 0)
371+
end
365372
end
366373

374+
enable_all!() = prctl(PR_TASK_PERF_EVENTS_ENABLE)
375+
disable_all!() = prctl(PR_TASK_PERF_EVENTS_DISABLE)
376+
367377
const PERF_EVENT_IOC_ENABLE = UInt64(0x2400)
368378
const PERF_EVENT_IOC_DISABLE = UInt64(0x2401)
369379
const PERF_EVENT_IOC_RESET = UInt64(0x2403)

0 commit comments

Comments
 (0)