1
0
Fork 0
cpu_ctrl/consumer/speed_controller.go

104 lines
2.5 KiB
Go
Raw Normal View History

package consumer
import (
"fmt"
"os/exec"
"time"
2018-07-06 01:42:09 +09:00
zlog "amuz.es/src/infra/goutils/logger/zap"
2017-09-11 00:37:01 +09:00
"bytes"
2018-07-06 01:42:09 +09:00
"amuz.es/src/infra/goutils/handler"
"amuz.es/src/infra/cpu_ctrl/producer"
"go.uber.org/zap"
2018-07-06 01:57:59 +09:00
"github.com/alecthomas/chroma/lexers/m"
2017-09-11 00:37:01 +09:00
)
2018-07-06 01:42:09 +09:00
var ()
type fanControl struct {
processorCount int
2018-07-06 01:42:09 +09:00
handler *handler.Handler
fanSpeedConsumer chan producer.FanspeedInfo
sampleDuration time.Duration
2018-07-06 01:42:09 +09:00
logger *zap.SugaredLogger
}
type FanControl interface {
2018-07-06 01:42:09 +09:00
Consumer() chan<- producer.FanspeedInfo
StartControl()
}
2018-07-06 01:42:09 +09:00
func NewFanControl(processorCount int, sampleDuration time.Duration, handler *handler.Handler) FanControl {
return &fanControl{
processorCount: processorCount,
handler: handler,
2018-07-06 01:42:09 +09:00
fanSpeedConsumer: make(chan producer.FanspeedInfo, processorCount),
sampleDuration: sampleDuration,
2018-07-06 01:42:09 +09:00
logger: zlog.New(nil, "fanspeed"),
}
}
2018-07-06 01:42:09 +09:00
func (c *fanControl) Consumer() chan<- producer.FanspeedInfo { return c.fanSpeedConsumer }
func (c *fanControl) StartControl() {
defer c.handler.DecreaseWait()
defer func() {
if err := recover(); err != nil {
c.handler.NotifyError(err.(error))
}
}()
2018-07-06 01:42:09 +09:00
defer c.logger.Info("Fan control stopped")
c.logger.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)
2018-07-06 01:57:59 +09:00
go func() {
for changedFanspeed := range c.fanSpeedConsumer {
newFanSpeedList[changedFanspeed.Id] = changedFanspeed.FanSpeed
}
}()
for {
2017-09-13 00:33:34 +09:00
select {
case <-ticker:
2017-09-13 00:53:45 +09:00
if !compareFanSpeed(pastFanSpeedList, newFanSpeedList) {
copy(pastFanSpeedList, newFanSpeedList)
go c.applyFanspeed(pastFanSpeedList)
}
2017-09-13 00:33:34 +09:00
case <-c.handler.Done():
return
}
}
}
2017-09-13 00:53:45 +09:00
func (c *fanControl) applyFanspeed(newFanSpeedList []int) {
2017-09-13 00:33:34 +09:00
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(' ')
}
2018-07-06 01:42:09 +09:00
c.logger.Infof("Commit fan speed with %s", buf.String())
2017-09-13 00:33:34 +09:00
}
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
}