2017-09-05 01:13:03 +09:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2017-09-06 07:53:17 +09:00
|
|
|
"errors"
|
2017-09-05 01:13:03 +09:00
|
|
|
"os"
|
|
|
|
"os/signal"
|
2017-09-10 16:28:50 +09:00
|
|
|
"runtime"
|
2017-09-05 01:13:03 +09:00
|
|
|
"syscall"
|
|
|
|
"time"
|
2017-09-07 01:26:04 +09:00
|
|
|
|
2017-09-10 16:28:50 +09:00
|
|
|
"amuz.es/src/infra/cpu_ctrl/daemon"
|
|
|
|
"amuz.es/src/infra/cpu_ctrl/logger"
|
|
|
|
"amuz.es/src/infra/cpu_ctrl/processor"
|
|
|
|
"amuz.es/src/infra/cpu_ctrl/util"
|
2017-09-11 00:22:51 +09:00
|
|
|
"amuz.es/src/infra/cpu_ctrl/consumer"
|
2017-09-05 01:13:03 +09:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2017-09-10 16:28:50 +09:00
|
|
|
log = logger.NewLogger("cpu_ctrl")
|
2017-09-05 01:13:03 +09:00
|
|
|
)
|
|
|
|
|
2017-09-10 16:28:50 +09:00
|
|
|
func init() {
|
|
|
|
logger.InitLogger(true, "", &logger.Config{FileName: "Stderr"})
|
|
|
|
setMaxProcs()
|
2017-09-05 01:13:03 +09:00
|
|
|
}
|
|
|
|
|
2017-09-10 16:28:50 +09:00
|
|
|
func setMaxProcs() {
|
|
|
|
// TODO(vmarmol): Consider limiting if we have a CPU mask in effect.
|
|
|
|
// Allow as many threads as we have cores unless the user specified a value.
|
|
|
|
var numProcs int
|
|
|
|
// if *maxProcs < 1 {
|
|
|
|
numProcs = runtime.NumCPU()
|
|
|
|
// } else {
|
|
|
|
// numProcs = *maxProcs
|
|
|
|
// }
|
|
|
|
runtime.GOMAXPROCS(numProcs)
|
|
|
|
|
|
|
|
// Check if the setting was successful.
|
|
|
|
actualNumProcs := runtime.GOMAXPROCS(0)
|
|
|
|
if actualNumProcs != numProcs {
|
|
|
|
log.Printf("Specified max procs of %v but using %v\n", numProcs, actualNumProcs)
|
2017-09-05 01:13:03 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-11 00:22:51 +09:00
|
|
|
func FanoutTempeture(sender <-chan processor.TempetureInfo, handler util.Handler, receivers ...chan<- processor.TempetureInfo) {
|
|
|
|
handler.IncreaseWait()
|
2017-09-10 19:45:30 +09:00
|
|
|
defer handler.DecreaseWait()
|
|
|
|
defer func() {
|
|
|
|
if err := recover(); err != nil {
|
|
|
|
handler.NotifyError(err.(error))
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case tempeture := <-sender:
|
|
|
|
for _, receiver := range receivers {
|
|
|
|
select {
|
|
|
|
case receiver <- tempeture:
|
|
|
|
default:
|
|
|
|
log.Warn("Some Tempeture consumer blocked!")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case <-handler.Done():
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-09-11 00:22:51 +09:00
|
|
|
|
2017-09-05 01:13:03 +09:00
|
|
|
func main() {
|
2017-09-10 19:45:30 +09:00
|
|
|
|
2017-09-05 01:13:03 +09:00
|
|
|
var (
|
2017-09-10 16:28:50 +09:00
|
|
|
processorCount = processor.GetProcessorCount()
|
|
|
|
processors []processor.Processor
|
|
|
|
exitSignal = make(chan os.Signal, 1)
|
|
|
|
handler = util.NewHandler()
|
|
|
|
sampleDuration = time.Second
|
2017-09-05 01:13:03 +09:00
|
|
|
)
|
2017-09-10 16:28:50 +09:00
|
|
|
log.Info("Cpu fan controller v0.2")
|
2017-09-05 01:13:03 +09:00
|
|
|
|
2017-09-06 07:53:17 +09:00
|
|
|
if processorCount == 0 {
|
2017-09-10 16:28:50 +09:00
|
|
|
handler.NotifyError(errors.New("cpu not found!"))
|
2017-09-06 07:53:17 +09:00
|
|
|
}
|
2017-09-10 16:28:50 +09:00
|
|
|
|
2017-09-11 00:22:51 +09:00
|
|
|
fanController := consumer.NewFanControl(processorCount, sampleDuration, handler)
|
|
|
|
|
2017-09-10 16:28:50 +09:00
|
|
|
processors = make([]processor.Processor, 0, processorCount)
|
2017-09-05 01:13:03 +09:00
|
|
|
for i := 0; i < processorCount; i++ {
|
2017-09-10 16:28:50 +09:00
|
|
|
if info, err := processor.NewProcessorInfo(handler, i, sampleDuration,
|
|
|
|
1.5, 0.4, 2.0, 38.0, 0x64, 0x4,
|
2017-09-11 00:22:51 +09:00
|
|
|
nil, fanController.Consumer(),
|
2017-09-10 16:28:50 +09:00
|
|
|
);
|
|
|
|
err != nil {
|
|
|
|
handler.NotifyError(err)
|
2017-09-06 07:53:17 +09:00
|
|
|
} else {
|
2017-09-10 16:28:50 +09:00
|
|
|
processors = append(processors, info)
|
2017-09-11 00:22:51 +09:00
|
|
|
handler.IncreaseWait()
|
2017-09-10 16:28:50 +09:00
|
|
|
go info.StartMonitoring()
|
2017-09-06 07:53:17 +09:00
|
|
|
}
|
2017-09-05 01:13:03 +09:00
|
|
|
}
|
2017-09-10 16:28:50 +09:00
|
|
|
|
|
|
|
handler.IncreaseWait()
|
2017-09-11 00:22:51 +09:00
|
|
|
go fanController.StartControl()
|
2017-09-10 16:28:50 +09:00
|
|
|
|
2017-09-05 01:13:03 +09:00
|
|
|
signal.Notify(exitSignal, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)
|
2017-09-10 16:28:50 +09:00
|
|
|
daemon.NotifyDaemon(daemon.DaemonStarted)
|
|
|
|
defer daemon.NotifyDaemon(daemon.DaemonStopping)
|
|
|
|
defer close(exitSignal)
|
|
|
|
defer handler.GracefullWait()
|
2017-09-05 01:13:03 +09:00
|
|
|
|
|
|
|
select {
|
2017-09-10 16:28:50 +09:00
|
|
|
case <-handler.Done():
|
|
|
|
log.Infoln("Service request to close this application")
|
|
|
|
case err := <-handler.Error():
|
|
|
|
log.Errorf("%s", err)
|
2017-09-05 01:13:03 +09:00
|
|
|
case sysSignal := <-exitSignal:
|
2017-09-10 16:28:50 +09:00
|
|
|
log.Warnf("SYSCALL! %s", sysSignal.String())
|
2017-09-05 01:13:03 +09:00
|
|
|
}
|
|
|
|
}
|