cpu_unix.go 1.0 KB

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