github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/qpc/qpc_windows.go (about) 1 package qpc 2 3 import ( 4 "syscall" 5 "time" 6 "unsafe" 7 ) 8 9 // precision timing 10 var ( 11 modkernel32 = syscall.NewLazyDLL("kernel32.dll") 12 procFreq = modkernel32.NewProc("QueryPerformanceFrequency") 13 procCounter = modkernel32.NewProc("QueryPerformanceCounter") 14 15 cachedFreq Count = getFrequency() 16 ) 17 18 // getFrequency returns frequency in ticks per second 19 func getFrequency() Count { 20 var freq int64 21 r1, _, _ := syscall.Syscall(procFreq.Addr(), 1, uintptr(unsafe.Pointer(&freq)), 0, 0) 22 if r1 == 0 { 23 panic("call failed") 24 } 25 return Count(freq) 26 } 27 28 // Now returns ticks 29 func Now() Count { 30 var now int64 31 r1, _, _ := syscall.Syscall(procCounter.Addr(), 1, uintptr(unsafe.Pointer(&now)), 0, 0) 32 if r1 == 0 { 33 panic("call failed") 34 } 35 return Count(now) 36 } 37 38 func (a Count) Sub(b Count) Count { return a - b } 39 40 func (count Count) Nanoseconds() int64 { 41 return int64(count * 1e9 / cachedFreq) 42 } 43 44 func (count Count) Duration() time.Duration { 45 return time.Duration(count) * time.Second / time.Duration(cachedFreq) 46 }