1
0
Fork 0
cpu_ctrl/consumer/speed_controller.go

101 lines
2.5 KiB
Go
Raw Normal View History

package consumer
import (
"fmt"
"os/exec"
"amuz.es/src/infra/cpu_ctrl/util"
"time"
"amuz.es/src/infra/cpu_ctrl/processor"
2017-09-11 00:37:01 +09:00
"amuz.es/src/infra/cpu_ctrl/logger"
"bytes"
)
var (
fanspeedLogger = logger.NewLogger("fanspeed")
)
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)
defer fanspeedLogger.Info("Fan control stopped")
fanspeedLogger.Info("Fan control started")
ticker := time.Tick(c.sampleDuration)
2017-09-13 00:33:34 +09:00
pastFanSpeedList, newFanSpeedList := make([]int, c.processorCount), make([]int, c.processorCount)
for {
2017-09-13 00:33:34 +09:00
select {
case <-ticker:
go c.applyFanspeed(pastFanSpeedList, newFanSpeedList)
pastFanSpeedList, newFanSpeedList = newFanSpeedList, make([]int, c.processorCount)
2017-09-13 00:42:29 +09:00
copy(newFanSpeedList, pastFanSpeedList)
2017-09-13 00:33:34 +09:00
case changedSpeed := <-c.fanSpeedConsumer:
newFanSpeedList[changedSpeed.Id] = changedSpeed.FanSpeed
case <-c.handler.Done():
return
}
}
}
2017-09-13 00:33:34 +09:00
func (c *fanControl) applyFanspeed(pastFanSpeedList, newFanSpeedList []int) {
if !compareFanSpeed(pastFanSpeedList, newFanSpeedList) {
return
}
args := make([]string, 0)
args = append(args, "raw", "0x3a", "0x01", )
for _, item := range newFanSpeedList {
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(' ')
}
fanspeedLogger.Infof("Commit fan speed with %s", buf.String())
}
func compareFanSpeed(old, new []int) bool {
2017-09-11 01:18:37 +09:00
new = new[:len(old)] // this line is the key
for i, v := range old {
if v != new[i] { // here is no bounds checking for b[i]
return false
}
}
return true
}