Skip to content

Commit 27bf87a

Browse files
committed
port over timer from google/benchmark
1 parent ef5bc08 commit 27bf87a

File tree

4 files changed

+219
-0
lines changed

4 files changed

+219
-0
lines changed

src/timers/darwin.jl

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
const RUSAGE_SELF = Cint(0)
2+
const RUSAGE_CHILDREN = Cint(-1)
3+
4+
struct timeval
5+
tv_sec::Clong
6+
tv_usec::Clong
7+
end
8+
9+
struct rusage
10+
ru_utime::timeval
11+
ru_stime::timeval
12+
ru_maxrss::Clong
13+
ru_ixrss::Clong
14+
ru_idrss::Clong
15+
ru_isrss::Clong
16+
ru_minflt::Clong
17+
ru_majflt::Clong
18+
ru_nswap::Clong
19+
ru_inblock::Clong
20+
ru_outblock::Clong
21+
ru_msgsnd::Clong
22+
ru_msgrcv::Clong
23+
ru_nsignals::Clong
24+
ru_nvcsw::Clong
25+
ru_nivcsw::Clong
26+
end
27+
28+
@inline function maketime(ru::rusage)
29+
user = ru.ru_utime.tv_sec * 1e9 + ru.ru_utime.tv_usec *1e3
30+
kernel = ru.ru_stime.tv_sec * 1e9 + ru.ru_stime.tv_usec *1e3
31+
return user+kernel
32+
end
33+
34+
struct time_value_t
35+
seconds::Cint
36+
microseconds::Cint
37+
end
38+
39+
struct thread_basic_info
40+
user_time::time_value_t
41+
system_time::time_value_t
42+
cpu_usage::Cint
43+
policy::Cint
44+
run_state::Cint
45+
flags::Cint
46+
suspend_count::Cint
47+
sleep_time::Cint
48+
end
49+
50+
@inline function maketime(info::thread_basic_info)
51+
user = info.user_time.seconds * 1e9 + info.user_time.microseconds * 1e3
52+
system = info.system_time.seconds * 1e9 + info.system_time.microseconds * 1e3
53+
return user+system
54+
end
55+
56+
@inline function walltime
57+
Base.time_ns()
58+
end
59+
60+
@inline function processtime()
61+
ru = Ref{rusage}()
62+
err = ccall(:getrusage, Cint, (Cint, Ref{rusage}), RUSAGE_SELF, ru)
63+
# TODO error check
64+
return maketime(ru[])
65+
end
66+
67+
const THREAD_BASIC_INFO_COUNT = (sizeof(thread_basic_info) ÷ sizeof(Int))
68+
69+
@inline function threadtime()
70+
#mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
71+
#thread_basic_info_data_t info;
72+
#mach_port_t thread = pthread_mach_thread_np(pthread_self());
73+
#if (thread_info(thread, THREAD_BASIC_INFO, (thread_info_t)&info, &count) ==
74+
# KERN_SUCCESS) {
75+
# return MakeTime(info);
76+
#}
77+
error("Thread time not implemented on OSX")
78+
end

src/timers/timers.jl

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#=
2+
Based upon https://github.com/google/benchmark
3+
=#
4+
5+
module Timers
6+
7+
"""
8+
walltime()
9+
10+
Monotonic runtime counter
11+
12+
Returns time in ns as Float64.
13+
"""
14+
function walltime end
15+
16+
"""
17+
processtime()
18+
19+
Process specific CPU time clock.
20+
21+
Returns time in ns as Float64.
22+
"""
23+
function processtime end
24+
25+
"""
26+
threadtime()
27+
28+
Thread specific CPU time clock.
29+
30+
Returns time in ns as Float64.
31+
"""
32+
function threadtime end
33+
34+
function _applever()
35+
return VersionNumber(readchomp(`sw_vers -productVersion`))
36+
end
37+
38+
if is_apple() && _applever() < v"10.12.0"
39+
include("darwin.jl")
40+
elseif is_unix()
41+
include("unix.jl")
42+
elseif is_windows()
43+
include("windows.jl")
44+
else
45+
error("$(Sys.Kernel) is not supported please file an issue")
46+
end
47+
end # module

src/timers/unix.jl

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
struct TimeSpec
2+
tv_sec :: UInt64 # time_t
3+
tv_nsec :: UInt64
4+
end
5+
6+
maketime(ts) = ts.tv_sec * 1e9 + ts.tv_nsec
7+
8+
# From bits/times.h on a Linux system
9+
# Check if those are the same on BSD
10+
if is_linux()
11+
const CLOCK_MONOTONIC = Cint(1)
12+
const CLOCK_PROCESS_CPUTIME_ID = Cint(2)
13+
const CLOCK_THREAD_CPUTIME_ID = Cint(3)
14+
elseif Sys.KERNEL == :FreeBSD # atleast on FreeBSD 11.1
15+
const CLOCK_MONOTONIC = Cint(4)
16+
const CLOCK_PROCESS_CPUTIME_ID = Cint(14)
17+
const CLOCK_THREAD_CPUTIME_ID = Cint(15)
18+
elseif is_apple() # Version 10.12 required
19+
const CLOCK_MONOTONIC = Cint(6)
20+
const CLOCK_PROCESS_CPUTIME_ID = Cint(12)
21+
const CLOCK_THREAD_CPUTIME_ID = Cint(16)
22+
else
23+
error("""
24+
BenchmarkTools doesn't currently support your system.
25+
Please file an issue, your kernel is $(Sys.KERNEL)
26+
""")
27+
end
28+
29+
@inline function clock_gettime(cid)
30+
ts = Ref{TimeSpec}()
31+
ccall(:clock_gettime, Cint, (Cint, Ref{TimeSpec}), cid, ts)
32+
return ts[]
33+
end
34+
35+
@inline function walltime()
36+
maketime(clock_gettime(CLOCK_MONOTONIC))
37+
end
38+
39+
@inline function processtime()
40+
maketime(clock_gettime(CLOCK_PROCESS_CPUTIME_ID))
41+
end
42+
43+
@inline function threadtime()
44+
maketime(clock_gettime(CLOCK_THREAD_CPUTIME_ID))
45+
end

src/timers/windows.jl

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
"""
2+
FileTime
3+
4+
See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284(v=vs.85).aspx
5+
"""
6+
struct FileTime
7+
dwHighDateTime::UInt32
8+
dwLowDateTime::UInt32
9+
end
10+
11+
const HANDLE = Ptr{Void}
12+
13+
@inline function maketime(kernel_time::FileTime, user_time::FileTime)
14+
kernel = (kernel_time.dwHighDateTime % UInt64) << 32 | kernel_time.dwLowDateTime
15+
user = ( user_time.dwHighDateTime % UInt64) << 32 | user_time.dwLowDateTime
16+
(kernel + user) * 1e2
17+
end
18+
19+
@inline function walltime()
20+
# counter = Ref{UInt64}()
21+
# err = ccall(:QueryPerformanceCounter, Cint, (Ref{UInt64},) )
22+
return Float64(Base.time_ns())
23+
end
24+
25+
@inline function processtime()
26+
proc = ccall(:GetCurrentProcess, HANDLE, ())
27+
creation_time = Ref{FileTime}()
28+
exit_time = Ref{FileTime}()
29+
kernel_time = Ref{FileTime}()
30+
user_time = Ref{FileTime}()
31+
32+
err = ccall(:GetProccessTimes, Cint, (HANDLE, Ref{FileTime}, Ref{FileTime}, Ref{FileTime}, Ref{FileTime}),
33+
proc, creation_time, exit_time, kernel_time, user_time)
34+
# TODO: Error handling
35+
return maketime(kernel_time, user_time)
36+
end
37+
38+
@inline function threadtime()
39+
thread = ccall(:GetCurrentThread, HANDLE, ())
40+
creation_time = Ref{FileTime}()
41+
exit_time = Ref{FileTime}()
42+
kernel_time = Ref{FileTime}()
43+
user_time = Ref{FileTime}()
44+
45+
err = ccall(:GetThreadTimes, Cint, (HANDLE, Ref{FileTime}, Ref{FileTime}, Ref{FileTime}, Ref{FileTime}),
46+
thread, creation_time, exit_time, kernel_time, user_time)
47+
# TODO: Error handling
48+
return maketime(kernel_time, user_time)
49+
end

0 commit comments

Comments
 (0)