timers.nim 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2012 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## Timer support for the realtime GC. Based on
  10. ## `<https://github.com/jckarter/clay/blob/master/compiler/hirestimer.cpp>`_
  11. type
  12. Ticks = distinct int64
  13. Nanos = int64
  14. when defined(windows):
  15. proc QueryPerformanceCounter(res: var Ticks) {.
  16. importc: "QueryPerformanceCounter", stdcall, dynlib: "kernel32".}
  17. proc QueryPerformanceFrequency(res: var int64) {.
  18. importc: "QueryPerformanceFrequency", stdcall, dynlib: "kernel32".}
  19. proc getTicks(): Ticks {.inline.} =
  20. QueryPerformanceCounter(result)
  21. proc `-`(a, b: Ticks): Nanos =
  22. var frequency: int64
  23. QueryPerformanceFrequency(frequency)
  24. var performanceCounterRate = 1e+9'f64 / float64(frequency)
  25. result = Nanos(float64(a.int64 - b.int64) * performanceCounterRate)
  26. elif defined(macosx) and not defined(emscripten):
  27. type
  28. MachTimebaseInfoData {.pure, final,
  29. importc: "mach_timebase_info_data_t",
  30. header: "<mach/mach_time.h>".} = object
  31. numer, denom: int32 # note: `uint32` in sources
  32. proc mach_absolute_time(): uint64 {.importc, header: "<mach/mach_time.h>".}
  33. proc mach_timebase_info(info: var MachTimebaseInfoData) {.importc,
  34. header: "<mach/mach_time.h>".}
  35. proc getTicks(): Ticks {.inline.} =
  36. result = Ticks(mach_absolute_time())
  37. var timeBaseInfo: MachTimebaseInfoData
  38. mach_timebase_info(timeBaseInfo)
  39. proc `-`(a, b: Ticks): Nanos =
  40. result = (a.int64 - b.int64) * timeBaseInfo.numer div timeBaseInfo.denom
  41. elif defined(posixRealtime):
  42. type
  43. Clockid {.importc: "clockid_t", header: "<time.h>", final.} = object
  44. TimeSpec {.importc: "struct timespec", header: "<time.h>",
  45. final, pure.} = object ## struct timespec
  46. tv_sec: int ## Seconds.
  47. tv_nsec: int ## Nanoseconds.
  48. var
  49. CLOCK_REALTIME {.importc: "CLOCK_REALTIME", header: "<time.h>".}: Clockid
  50. proc clock_gettime(clkId: Clockid, tp: var Timespec) {.
  51. importc: "clock_gettime", header: "<time.h>".}
  52. proc getTicks(): Ticks =
  53. var t: Timespec
  54. clock_gettime(CLOCK_REALTIME, t)
  55. result = Ticks(int64(t.tv_sec) * 1000000000'i64 + int64(t.tv_nsec))
  56. proc `-`(a, b: Ticks): Nanos {.borrow.}
  57. else:
  58. # fallback Posix implementation:
  59. when not declared(Time):
  60. when defined(linux):
  61. type Time = clong
  62. else:
  63. type Time = int
  64. type
  65. Timeval {.importc: "struct timeval", header: "<sys/select.h>",
  66. final, pure.} = object ## struct timeval
  67. tv_sec: Time ## Seconds.
  68. tv_usec: clong ## Microseconds.
  69. proc posix_gettimeofday(tp: var Timeval, unused: pointer = nil) {.
  70. importc: "gettimeofday", header: "<sys/time.h>".}
  71. proc getTicks(): Ticks =
  72. var t: Timeval
  73. posix_gettimeofday(t)
  74. result = Ticks(int64(t.tv_sec) * 1000_000_000'i64 +
  75. int64(t.tv_usec) * 1000'i64)
  76. proc `-`(a, b: Ticks): Nanos {.borrow.}