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  }