This repository has been archived by the owner on Dec 16, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
114 lines (98 loc) · 1.73 KB
/
main.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package main
import (
"errors"
"fmt"
"io/ioutil"
"math/rand"
"regexp"
"runtime"
"strconv"
"time"
)
func main() {
// take the current max from /proc/cpuinfo
fmt.Printf("read current speed: %.2f\n", ReadSpeedCPU())
// load CPU and take measurements
fmt.Printf("loaded max speed: %.2f\n", LoadedSpeedCPU())
}
var (
cpuInfoRe = regexp.MustCompile(`cpu MHz[\s]+:[\s]+([\.\d]+)`)
)
func ReadSpeedCPU() float64 {
speed, err := mhz("/proc/cpuinfo")
if err != nil {
panic(err)
}
return speed
}
func LoadedSpeedCPU() float64 {
speed, err := measure()
if err != nil {
panic(err)
}
return speed
}
func measure() (float64, error) {
timerC := time.After(200 * time.Millisecond)
stopC := make(chan struct{})
go load(stopC)
max := 0.0
for {
select {
case <-timerC:
stopC <- struct{}{}
return max, nil
case <-time.After(20 * time.Millisecond):
speed, err := mhz("/proc/cpuinfo")
if err != nil {
return 0, err
}
if speed > max {
max = speed
}
}
}
}
type measurment struct {
speed float64
err error
}
func load(stopC <-chan struct{}) {
runtime.LockOSThread()
for {
select {
case <-stopC:
return
default:
}
if busy() {
return
}
}
}
func busy() bool {
// trick the compiler into doing some work
// rand.Int is always positive
return (0x5353&rand.Int())<<1 < 0
}
func mhz(file string) (float64, error) {
b, err := ioutil.ReadFile(file)
if err != nil {
return 0, err
}
matches := cpuInfoRe.FindStringSubmatch(string(b))
if len(matches) < 2 {
return 0, errors.New("cpu mhz not found")
}
max := 0.0
for _, match := range matches[1:] {
mhz, err := strconv.ParseFloat(match, 64)
if err != nil {
return 0, err
}
if mhz > max {
max = mhz
}
}
return max, nil
}