02-cpu.go (2443B)
1 package status // import "hhvn.uk/hbspbar/status" 2 3 import ( 4 "fmt" 5 "errors" 6 "strings" 7 8 "hhvn.uk/hbspbar/common" 9 ) 10 11 func getcpus(c chan [][]string, e chan error) { 12 var ret [][]string 13 14 lines, err := common.FileAsLines("/proc/stat") 15 if err != nil { 16 c <- nil 17 e <- err 18 return 19 } 20 21 for _, l := range lines { 22 var tok []string 23 24 tokempty := strings.Split(l, " ") 25 26 if !strings.HasPrefix(tokempty[0], "cpu") || 27 strings.HasSuffix(tokempty[0], "u") { 28 continue 29 } 30 31 for _, t := range tokempty { 32 if t != "" { tok = append(tok, t) } 33 } 34 35 ret = append(ret, tok) 36 } 37 38 c <- ret 39 40 if ret == nil { 41 e <- errors.New("apparently this computer has no cores") 42 } 43 } 44 45 func cpu(u *Block) error { 46 cpus := [2]chan [][]string{ 47 make(chan [][]string), 48 make(chan [][]string) } 49 50 cpuerr := [2]chan error{ 51 make(chan error), 52 make(chan error) } 53 54 go getcpus(cpus[0], cpuerr[0]) 55 sleep(1) 56 go getcpus(cpus[1], cpuerr[1]) 57 58 start := <- cpus[0] 59 if start == nil { return <- cpuerr[0] } 60 61 end := <- cpus[1] 62 if end == nil { return <- cpuerr[1] } 63 64 if len(start) != len(end) { 65 return errors.New("somehow we lost/gained some cores") 66 } 67 68 ncores := len(start) 69 70 total := make([]int, ncores) 71 idle := make([]int, ncores) 72 73 for i, c := range start { 74 for j, v := range c { 75 if j == 0 { continue } 76 n, err := common.Intify(v) 77 if err != nil { return err } 78 total[i] += n 79 } 80 81 n, err := common.Intify(c[4]) 82 if err != nil { return err } 83 idle[i] = n 84 } 85 86 cx := 0 87 88 for i, c := range end { 89 ltotal := 0 90 91 for j, v := range c { 92 if j == 0 { continue } 93 n, err := common.Intify(v) 94 if err != nil { return err } 95 ltotal += n 96 } 97 98 n, err := common.Intify(c[4]) 99 if err != nil { return err } 100 lidle := n - idle[i] 101 ltotal = ltotal - total[i] 102 used := int((100 * (ltotal - lidle)) / ltotal) 103 104 cx += u.drawPercentBar(cx, used) 105 } 106 107 temps := 0 108 109 for i := 0; i < ncores; i ++ { 110 file := fmt.Sprintf("/sys/class/thermal/thermal_zone%d/temp", i) 111 content, err := common.FileAsLines(file) 112 if err != nil { return err } 113 114 n, err := common.Intify(content[0]) 115 if err != nil { return err } 116 117 temps += n / 1000 118 } 119 120 // <=40: green. >=80: red. 121 cp := float64(temps/ncores - 40) 122 cp /= 40 123 cp *= 100 124 if cp > 100 { cp = 100 } 125 126 u.drawText(cx, blendGYR(int(cp)), fmt.Sprintf("%d°C", temps / ncores)) 127 128 return nil 129 } 130 131 func init() { 132 // 0 second interval, as there is already a 1 second sleep in cpu() 133 register("cpu", cpu, 0) 134 }