mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
profile: use specialized time__vpc_now
This commit is contained in:
@@ -10,31 +10,29 @@ const (
|
||||
|
||||
[typedef]
|
||||
struct C.mach_timebase_info_data_t {
|
||||
numer u64
|
||||
denom u64
|
||||
numer u32
|
||||
denom u32
|
||||
}
|
||||
|
||||
fn C.mach_absolute_time() u64
|
||||
fn C.mach_timebase_info(&C.mach_timebase_info_data_t)
|
||||
fn C.clock_gettime_nsec_np(int) u64
|
||||
|
||||
struct InternalTimeBase {
|
||||
numer u64
|
||||
denom u64
|
||||
numer u32 = 1
|
||||
denom u32 = 1
|
||||
}
|
||||
|
||||
fn init_time_base() InternalTimeBase {
|
||||
mut tb := C.mach_timebase_info_data_t{}
|
||||
tb := C.mach_timebase_info_data_t{}
|
||||
C.mach_timebase_info(&tb)
|
||||
return InternalTimeBase{numer:tb.numer, denom:tb.denom}
|
||||
}
|
||||
|
||||
fn sys_mono_now_darwin() u64 {
|
||||
tm := C.mach_absolute_time()
|
||||
return mul_div(tm - start_time, time_base.numer, time_base.denom)
|
||||
}
|
||||
|
||||
fn mul_div(val, numer, denom u64) u64 {
|
||||
q := val / denom
|
||||
r := val % denom
|
||||
return q * numer + r * numer / denom
|
||||
if time_base.denom == 0 {
|
||||
C.mach_timebase_info(&time_base)
|
||||
}
|
||||
return (tm - start_time) * time_base.numer / time_base.denom
|
||||
}
|
||||
|
||||
@@ -39,3 +39,19 @@ fn sys_mono_now() u64 {
|
||||
}
|
||||
}
|
||||
|
||||
// NB: vpc_now is used by `v -profile` .
|
||||
// It should NOT call *any other v function*, just C functions and casts.
|
||||
[inline]
|
||||
fn vpc_now() u64 {
|
||||
$if macos {
|
||||
tm := C.mach_absolute_time()
|
||||
if time_base.denom == 0 {
|
||||
C.mach_timebase_info(&time_base)
|
||||
}
|
||||
return (tm - start_time) * time_base.numer / time_base.denom
|
||||
} $else {
|
||||
ts := C.timespec{}
|
||||
C.clock_gettime(C.CLOCK_MONOTONIC, &ts)
|
||||
return u64(ts.tv_sec) * 1_000_000_000 + u64(ts.tv_nsec)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,48 +12,46 @@ struct C.tm {
|
||||
tm_sec int
|
||||
}
|
||||
|
||||
[typedef]
|
||||
struct C.LARGE_INTEGER {
|
||||
QuadPart i64
|
||||
}
|
||||
|
||||
const (
|
||||
// start_time is needed on Darwin and Windows because of potential overflows
|
||||
// Windows: don't store the LARGE_INTEGER, just the QuadPart
|
||||
start_time = init_win_time_start()
|
||||
freq_time = init_win_time_freq()
|
||||
)
|
||||
|
||||
fn C._mkgmtime(&C.tm) time_t
|
||||
|
||||
fn C.QueryPerformanceCounter(&C.LARGE_INTEGER) C.BOOL
|
||||
fn C.QueryPerformanceCounter(&u64) C.BOOL
|
||||
|
||||
fn C.QueryPerformanceFrequency(&C.LARGE_INTEGER) C.BOOL
|
||||
fn C.QueryPerformanceFrequency(&u64) C.BOOL
|
||||
|
||||
fn make_unix_time(t C.tm) int {
|
||||
return int(C._mkgmtime(&t))
|
||||
}
|
||||
|
||||
fn init_win_time_freq() u64 {
|
||||
mut f := C.LARGE_INTEGER{}
|
||||
_ := C.QueryPerformanceFrequency(&f)
|
||||
return u64(f.QuadPart)
|
||||
f := u64(0)
|
||||
C.QueryPerformanceFrequency(&f)
|
||||
return f
|
||||
}
|
||||
|
||||
fn init_win_time_start() u64 {
|
||||
mut s := C.LARGE_INTEGER{}
|
||||
_ := C.QueryPerformanceCounter(&s)
|
||||
return u64(s.QuadPart)
|
||||
s := u64(0)
|
||||
C.QueryPerformanceCounter(&s)
|
||||
return s
|
||||
}
|
||||
|
||||
fn sys_mono_now() u64 {
|
||||
mut tm := C.LARGE_INTEGER{}
|
||||
_ := C.QueryPerformanceCounter(&tm) // XP or later never fail
|
||||
return mul_div(u64(tm.QuadPart) - start_time, 1_000_000_000, freq_time)
|
||||
tm := u64(0)
|
||||
C.QueryPerformanceCounter(&tm) // XP or later never fail
|
||||
return (tm - start_time) * 1_000_000_000 / freq_time
|
||||
}
|
||||
|
||||
fn mul_div(val, numer, denom u64) u64 {
|
||||
q := val / denom
|
||||
r := val % denom
|
||||
return q * numer + r * numer / denom
|
||||
// NB: vpc_now is used by `v -profile` .
|
||||
// It should NOT call *any other v function*, just C functions and casts.
|
||||
[inline]
|
||||
fn vpc_now() u64 {
|
||||
tm := u64(0)
|
||||
C.QueryPerformanceCounter(&tm)
|
||||
return tm
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user