cpuusage.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. // Copyright (C) 2017 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package main
  7. import (
  8. "math"
  9. "time"
  10. metrics "github.com/rcrowley/go-metrics"
  11. )
  12. const cpuTickRate = 5 * time.Second
  13. type cpuService struct {
  14. avg metrics.EWMA
  15. stop chan struct{}
  16. }
  17. func newCPUService() *cpuService {
  18. return &cpuService{
  19. // 10 second average. Magic alpha value comes from looking at EWMA package
  20. // definitions of EWMA1, EWMA5. The tick rate *must* be five seconds (hard
  21. // coded in the EWMA package).
  22. avg: metrics.NewEWMA(1 - math.Exp(-float64(cpuTickRate)/float64(time.Second)/10.0)),
  23. stop: make(chan struct{}),
  24. }
  25. }
  26. func (s *cpuService) Serve() {
  27. // Initialize prevUsage to an actual value returned by cpuUsage
  28. // instead of zero, because at least Windows returns a huge negative
  29. // number here that then slowly increments...
  30. prevUsage := cpuUsage()
  31. ticker := time.NewTicker(cpuTickRate)
  32. defer ticker.Stop()
  33. for {
  34. select {
  35. case <-ticker.C:
  36. curUsage := cpuUsage()
  37. s.avg.Update(int64((curUsage - prevUsage) / time.Millisecond))
  38. prevUsage = curUsage
  39. s.avg.Tick()
  40. case <-s.stop:
  41. return
  42. }
  43. }
  44. }
  45. func (s *cpuService) Stop() {
  46. close(s.stop)
  47. }
  48. func (s *cpuService) Rate() float64 {
  49. return s.avg.Rate()
  50. }