hbspbar

bspwm status bar
git clone https://hhvn.uk/hbspbar
git clone git://hhvn.uk/hbspbar
Log | Files | Refs

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 }