1
0
Fork 0
cpu_ctrl/consumer/speed_controller.go

99 lines
2.3 KiB
Go

package consumer
import (
"fmt"
"os/exec"
"amuz.es/src/infra/cpu_ctrl/util"
"time"
"amuz.es/src/infra/cpu_ctrl/processor"
"amuz.es/src/infra/cpu_ctrl/logger"
"bytes"
)
var (
log = logger.NewLogger("consumer")
)
type fanControl struct {
processorCount int
handler util.Handler
fanSpeedConsumer chan processor.FanspeedInfo
sampleDuration time.Duration
}
type FanControl interface {
Consumer() chan<- processor.FanspeedInfo
StartControl()
}
func NewFanControl(processorCount int, sampleDuration time.Duration, handler util.Handler) FanControl {
return &fanControl{
processorCount: processorCount,
handler: handler,
fanSpeedConsumer: make(chan processor.FanspeedInfo, processorCount),
sampleDuration: sampleDuration,
}
}
func (c *fanControl) Consumer() chan<- processor.FanspeedInfo { return c.fanSpeedConsumer }
func (c *fanControl) StartControl() {
defer c.handler.DecreaseWait()
defer func() {
if err := recover(); err != nil {
c.handler.NotifyError(err.(error))
}
}()
defer close(c.fanSpeedConsumer)
log.Info("Fan control started")
ticker := time.Tick(c.sampleDuration)
fanSpeedList := make([]int, c.processorCount)
for {
newFanSpeedList := make([]int, c.processorCount)
checker:
for {
select {
case <-ticker:
break checker
case changedSpeed := <-c.fanSpeedConsumer:
newFanSpeedList[changedSpeed.Id] = changedSpeed.FanSpeed
case <-c.handler.Done():
return
}
}
if (!compareFanSpeed(fanSpeedList, newFanSpeedList)) {
copy(fanSpeedList, newFanSpeedList)
args := make([]string, 0)
args = append(args, "raw", "0x3a", "0x01", )
for _, item := range fanSpeedList {
args = append(args, fmt.Sprintf("0x%x", item))
}
args = append(args,
"0x0", "0x0", "0x0", "0x0", "0x0", "0x0",
)
cmd := exec.Command("ipmitool", args...)
if err := cmd.Run(); err != nil {
c.handler.NotifyError(err)
return
}
buf := bytes.NewBufferString("")
for _, item := range newFanSpeedList {
buf.WriteString(fmt.Sprintf("0x%x", item))
buf.WriteRune(' ')
}
log.Infof("Commit fan speed with %s", buf.String())
}
}
}
func compareFanSpeed(old, new []int) bool {
for i, v := range old {
if v != new[i] { // here is no bounds checking for b[i]
return false
}
}
return true
}