time_windows.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. // Unless explicitly stated otherwise all files in this repository are licensed
  2. // under the Apache License Version 2.0.
  3. // This product includes software developed at Datadog (https://www.datadoghq.com/).
  4. // Copyright 2016 Datadog, Inc.
  5. package tracer
  6. import (
  7. "time"
  8. "golang.org/x/sys/windows"
  9. "gopkg.in/DataDog/dd-trace-go.v1/internal/log"
  10. )
  11. // This method is more precise than the go1.8 time.Now on Windows
  12. // See https://msdn.microsoft.com/en-us/library/windows/desktop/hh706895(v=vs.85).aspx
  13. // It is however ~10x slower and requires Windows 8+.
  14. func highPrecisionNow() int64 {
  15. var ft windows.Filetime
  16. windows.GetSystemTimePreciseAsFileTime(&ft)
  17. return ft.Nanoseconds()
  18. }
  19. func lowPrecisionNow() int64 {
  20. return time.Now().UnixNano()
  21. }
  22. // We use this method of initializing now over an init function due to dependency issues. The init
  23. // function may run after other declarations, such as that in payload_test:19, which results in a
  24. // nil dereference panic.
  25. var now func() int64 = func() func() int64 {
  26. if err := windows.LoadGetSystemTimePreciseAsFileTime(); err != nil {
  27. log.Warn("Unable to load high precison timer, defaulting to time.Now()")
  28. return lowPrecisionNow
  29. } else {
  30. return highPrecisionNow
  31. }
  32. }()
  33. var nowTime func() time.Time = func() func() time.Time {
  34. if err := windows.LoadGetSystemTimePreciseAsFileTime(); err != nil {
  35. log.Warn("Unable to load high precison timer, defaulting to time.Now()")
  36. return func() time.Time { return time.Unix(0, lowPrecisionNow()) }
  37. } else {
  38. return func() time.Time { return time.Unix(0, highPrecisionNow()) }
  39. }
  40. }()