-
Notifications
You must be signed in to change notification settings - Fork 151
/
cpu_usage.go
90 lines (74 loc) · 1.92 KB
/
cpu_usage.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package spammer
import (
"context"
"math/rand"
"runtime"
"time"
"github.com/pkg/errors"
"github.com/shirou/gopsutil/cpu"
"github.com/gohornet/hornet/pkg/common"
)
const (
cpuUsageSampleTime = 200 * time.Millisecond
cpuUsageSleepTime = int(200 * time.Millisecond)
)
var (
// ErrCPUPercentageUnknown is returned if the CPU usage couldn't be determined.
ErrCPUPercentageUnknown = errors.New("CPU percentage unknown")
)
// cpuUsageUpdater starts a goroutine that computes cpu usage each cpuUsageSampleTime.
func cpuUsageUpdater() {
go func() {
for {
if Plugin.Daemon().IsStopped() {
return
}
cpuUsagePSutil, err := cpu.Percent(cpuUsageSampleTime, false)
cpuUsageLock.Lock()
if err != nil {
cpuUsageError = ErrCPUPercentageUnknown
cpuUsageLock.Unlock()
return
}
cpuUsageError = nil
cpuUsageResult = cpuUsagePSutil[0] / 100.0
cpuUsageLock.Unlock()
}
}()
}
// cpuUsage returns latest cpu usage
func cpuUsage() (float64, error) {
cpuUsageLock.RLock()
defer cpuUsageLock.RUnlock()
return cpuUsageResult, cpuUsageError
}
// cpuUsageGuessWithAdditionalWorker returns guessed cpu usage with another core running at 100% load
func cpuUsageGuessWithAdditionalWorker() (float64, error) {
cpuUsage, err := cpuUsage()
if err != nil {
return 0.0, err
}
return cpuUsage + (1.0 / float64(runtime.NumCPU())), nil
}
// waitForLowerCPUUsage waits until the cpu usage drops below cpuMaxUsage.
func waitForLowerCPUUsage(ctx context.Context, cpuMaxUsage float64) error {
if cpuMaxUsage == 0.0 {
return nil
}
for {
cpuUsage, err := cpuUsageGuessWithAdditionalWorker()
if err != nil {
return err
}
if cpuUsage < cpuMaxUsage {
break
}
select {
case <-ctx.Done():
return common.ErrOperationAborted
case <-time.After(time.Duration(cpuUsageSleepTime + rand.Intn(cpuUsageSleepTime))):
// sleep a random time between cpuUsageSleepTime and 2*cpuUsageSleepTime
}
}
return nil
}