88 lines
1.9 KiB
Go
88 lines
1.9 KiB
Go
|
package consumer
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"os/exec"
|
||
|
"amuz.es/src/infra/cpu_ctrl/util"
|
||
|
"time"
|
||
|
"amuz.es/src/infra/cpu_ctrl/processor"
|
||
|
)
|
||
|
|
||
|
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)
|
||
|
|
||
|
ticker := time.Tick(c.sampleDuration)
|
||
|
fanSpeedList := make([]int, c.processorCount)
|
||
|
|
||
|
for {
|
||
|
newFanSpeedList := make([]int, c.processorCount)
|
||
|
for {
|
||
|
select {
|
||
|
case <-ticker:
|
||
|
break
|
||
|
case changedSpeed := <-c.fanSpeedConsumer:
|
||
|
newFanSpeedList[changedSpeed.Id] = changedSpeed.FanSpeed
|
||
|
case <-c.handler.Done():
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
if (compareFanSpeed(fanSpeedList, newFanSpeedList)) {
|
||
|
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
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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
|
||
|
}
|