cpu_unix.go 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. //go:build unix
  2. package cpu
  3. // #include <time.h>
  4. import "C"
  5. import (
  6. "runtime"
  7. "time"
  8. )
  9. var cpuCount = runtime.GOMAXPROCS(0)
  10. // probe the CPU usage of the process
  11. // if CPUs are not busy, most threads are likely waiting for I/O, so we should scale
  12. // if CPUs are already busy we won't gain much by scaling and want to avoid the overhead of doing so
  13. func ProbeCPUs(probeTime time.Duration, maxCPUUsage float64, abort chan struct{}) bool {
  14. var cpuStart, cpuEnd C.struct_timespec
  15. // note: clock_gettime is a POSIX function
  16. // on Windows we'd need to use QueryPerformanceCounter instead
  17. start := time.Now()
  18. C.clock_gettime(C.CLOCK_PROCESS_CPUTIME_ID, &cpuStart)
  19. select {
  20. case <-abort:
  21. return false
  22. case <-time.After(probeTime):
  23. }
  24. C.clock_gettime(C.CLOCK_PROCESS_CPUTIME_ID, &cpuEnd)
  25. elapsedTime := float64(time.Since(start).Nanoseconds())
  26. elapsedCpuTime := float64(cpuEnd.tv_sec-cpuStart.tv_sec)*1e9 + float64(cpuEnd.tv_nsec-cpuStart.tv_nsec)
  27. cpuUsage := elapsedCpuTime / elapsedTime / float64(cpuCount)
  28. return cpuUsage < maxCPUUsage
  29. }