/timer.nim Secret
Last active
March 21, 2019 11:30
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Chronos Timer | |
# | |
# (c) Copyright 2017 Eugene Kabanov | |
# (c) Copyright 2018-Present Status Research & Development GmbH | |
# | |
# Licensed under either of | |
# Apache License, version 2.0, (LICENSE-APACHEv2) | |
# MIT license (LICENSE-MIT) | |
## This module implements cross-platform system timer with | |
## milliseconds resolution. | |
when defined(windows): | |
var queryFrequency: uint64 | |
proc QueryPerformanceCounter(res: var uint64) {. | |
importc: "QueryPerformanceCounter", stdcall, dynlib: "kernel32".} | |
proc QueryPerformanceFrequency(res: var uint64) {. | |
importc: "QueryPerformanceFrequency", stdcall, dynlib: "kernel32".} | |
from winlean import DWORD, getSystemTimeAsFileTime, FILETIME | |
proc fastEpochTime*(): uint64 {.inline.} = | |
var t: FILETIME | |
getSystemTimeAsFileTime(t) | |
result = ((uint64(t.dwHighDateTime) shl 32) or | |
uint64(t.dwLowDateTime)) div 10_000 | |
proc fastEpochTimeMono*(): uint64 {.inline.} = | |
var res: uint64 | |
QueryPerformanceCounter(res) | |
result = res * queryFrequency | |
proc setupQueryFrequence() = | |
var freq: uint64 | |
QueryPerformanceFrequency(freq) | |
queryFrequency = 1_000_000_000'u64 div freq | |
setupQueryFrequence() | |
elif defined(macosx): | |
from posix import Timeval | |
proc posix_gettimeofday(tp: var Timeval, unused: pointer = nil) {. | |
importc: "gettimeofday", header: "<sys/time.h>".} | |
proc fastEpochTime*(): uint64 {.inline.} = | |
var t: Timeval | |
posix_gettimeofday(t) | |
result = (uint64(t.tv_sec) * 1_000 + uint64(t.tv_usec) div 1_000) | |
elif defined(posix): | |
from posix import clock_gettime, Timespec, CLOCK_REALTIME, CLOCK_MONOTONIC | |
const CLOCK_MONOTONIC_RAW = cint(4) | |
proc fastEpochTime*(): uint64 {.inline.} = | |
var t: Timespec | |
discard clock_gettime(CLOCK_REALTIME, t) | |
result = (uint64(t.tv_sec) * 1_000_000_000 + uint64(t.tv_nsec)) | |
proc fastEpochTimeMono*(): uint64 {.inline.} = | |
var t: Timespec | |
discard clock_gettime(CLOCK_MONOTONIC, t) | |
result = (uint64(t.tv_sec) * 1_000_000_000 + uint64(t.tv_nsec)) | |
proc fastEpochTimeRaw*(): uint64 {.inline.} = | |
var t: Timespec | |
discard clock_gettime(CLOCK_MONOTONIC_RAW, t) | |
result = (uint64(t.tv_sec) * 1_000_000_000 + uint64(t.tv_nsec)) | |
elif defined(nimdoc): | |
proc fastEpochTime*(): uint64 | |
## Returns system's timer in milliseconds. | |
else: | |
error("Sorry, your operation system is not yet supported!") | |
when isMainModule: | |
when defined(windows): | |
var a, b: uint64 | |
for i in 1..10: | |
a = fastEpochTimeMono() | |
for i in 1..100_000_000: | |
var d = fastEpochTimeMono() | |
b = fastEpochTimeMono() | |
echo "100_000_000 calls to fastEpochTimeMono() takes ", (b - a), "ns" | |
a = fastEpochTimeMono() | |
for i in 1..100_000_000: | |
var d = fastEpochTime() | |
b = fastEpochTimeMono() | |
echo "100_000_000 calls to fastEpochTime() takes ", (b - a), "ns" | |
elif defined(linux): | |
var a, b: uint64 | |
for i in 1..10: | |
a = fastEpochTimeMono() | |
for i in 1..100_000_000: | |
var d = fastEpochTimeMono() | |
b = fastEpochTimeMono() | |
echo "100_000_000 calls to fastEpochTimeMono() takes ", (b - a), "ns" | |
a = fastEpochTimeMono() | |
for i in 1..100_000_000: | |
var d = fastEpochTime() | |
b = fastEpochTimeMono() | |
echo "100_000_000 calls to fastEpochTime() takes ", (b - a), "ns" | |
a = fastEpochTimeMono() | |
for i in 1..100_000_000: | |
var d = fastEpochTimeRaw() | |
b = fastEpochTimeMono() | |
echo "100_000_000 calls to fastEpochTimeRaw() takes ", (b - a), "ns" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment