@@ -14,17 +14,8 @@ import (
14
14
"golang.org/x/sys/unix"
15
15
)
16
16
17
- import "C"
18
-
19
17
const (
20
18
// sys/sched.h
21
- cpUser = 0
22
- cpNice = 1
23
- cpSys = 2
24
- cpSpin = 3
25
- cpIntr = 4
26
- cpIdle = 5
27
- cpuStates = 6
28
19
cpuOnline = 0x0001 // CPUSTATS_ONLINE
29
20
30
21
// sys/sysctl.h
@@ -37,6 +28,19 @@ const (
37
28
38
29
var ClocksPerSec = float64 (128 )
39
30
31
+ type cpuStats struct {
32
+ // cs_time[CPUSTATES]
33
+ User uint64
34
+ Nice uint64
35
+ Sys uint64
36
+ Spin uint64
37
+ Intr uint64
38
+ Idle uint64
39
+
40
+ // cs_flags
41
+ Flags uint64
42
+ }
43
+
40
44
func init () {
41
45
clkTck , err := sysconf .Sysconf (sysconf .SC_CLK_TCK )
42
46
// ignore errors
@@ -49,33 +53,23 @@ func Times(percpu bool) ([]TimesStat, error) {
49
53
return TimesWithContext (context .Background (), percpu )
50
54
}
51
55
52
- func cpsToTS (cpuTimes []uint64 , name string ) TimesStat {
53
- return TimesStat {
54
- CPU : name ,
55
- User : float64 (cpuTimes [cpUser ]) / ClocksPerSec ,
56
- Nice : float64 (cpuTimes [cpNice ]) / ClocksPerSec ,
57
- System : float64 (cpuTimes [cpSys ]) / ClocksPerSec ,
58
- Idle : float64 (cpuTimes [cpIdle ]) / ClocksPerSec ,
59
- Irq : float64 (cpuTimes [cpIntr ]) / ClocksPerSec ,
60
- }
61
- }
62
-
63
56
func TimesWithContext (ctx context.Context , percpu bool ) (ret []TimesStat , err error ) {
64
57
if ! percpu {
65
58
mib := []int32 {ctlKern , kernCpTime }
66
59
buf , _ , err := common .CallSyscall (mib )
67
60
if err != nil {
68
61
return ret , err
69
62
}
70
- var x []C.long
71
- // could use unsafe.Slice but it's only for go1.17+
72
- x = (* [cpuStates ]C.long )(unsafe .Pointer (& buf [0 ]))[:]
73
- cpuTimes := [cpuStates ]uint64 {}
74
- for i := range x {
75
- cpuTimes [i ] = uint64 (x [i ])
63
+ times := (* cpuTimes )(unsafe .Pointer (& buf [0 ]))
64
+ stat := TimesStat {
65
+ CPU : "cpu-total" ,
66
+ User : float64 (times .User ) / ClocksPerSec ,
67
+ Nice : float64 (times .Nice ) / ClocksPerSec ,
68
+ System : float64 (times .Sys ) / ClocksPerSec ,
69
+ Idle : float64 (times .Idle ) / ClocksPerSec ,
70
+ Irq : float64 (times .Intr ) / ClocksPerSec ,
76
71
}
77
- c := cpsToTS (cpuTimes [:], "cpu-total" )
78
- return []TimesStat {c }, nil
72
+ return []TimesStat {stat }, nil
79
73
}
80
74
81
75
ncpu , err := unix .SysctlUint32 ("hw.ncpu" )
@@ -91,17 +85,18 @@ func TimesWithContext(ctx context.Context, percpu bool) (ret []TimesStat, err er
91
85
return ret , err
92
86
}
93
87
94
- data := unsafe .Pointer (& buf [0 ])
95
- fptr := unsafe .Pointer (uintptr (data ) + uintptr (8 * cpuStates ))
96
- flags := * (* uint64 )(fptr )
97
- if (flags & cpuOnline ) == 0 {
88
+ stats := (* cpuStats )(unsafe .Pointer (& buf [0 ]))
89
+ if (stats .Flags & cpuOnline ) == 0 {
98
90
continue
99
91
}
100
-
101
- var x []uint64
102
- x = (* [cpuStates ]uint64 )(data )[:]
103
- c := cpsToTS (x , fmt .Sprintf ("cpu%d" , i ))
104
- ret = append (ret , c )
92
+ ret = append (ret , TimesStat {
93
+ CPU : fmt .Sprintf ("cpu%d" , i ),
94
+ User : float64 (stats .User ) / ClocksPerSec ,
95
+ Nice : float64 (stats .Nice ) / ClocksPerSec ,
96
+ System : float64 (stats .Sys ) / ClocksPerSec ,
97
+ Idle : float64 (stats .Idle ) / ClocksPerSec ,
98
+ Irq : float64 (stats .Intr ) / ClocksPerSec ,
99
+ })
105
100
}
106
101
107
102
return ret , nil
0 commit comments