2016-06-10 21:46:33 +00:00
|
|
|
package stats
|
|
|
|
|
|
|
|
import (
|
2018-05-08 21:00:31 +00:00
|
|
|
"context"
|
2016-06-17 19:13:53 +00:00
|
|
|
"fmt"
|
2016-06-22 22:01:36 +00:00
|
|
|
"math"
|
2016-06-11 15:31:49 +00:00
|
|
|
"sync"
|
2018-05-08 21:00:31 +00:00
|
|
|
"time"
|
2016-06-17 19:13:53 +00:00
|
|
|
|
2017-06-27 18:54:15 +00:00
|
|
|
multierror "github.com/hashicorp/go-multierror"
|
2016-06-17 19:13:53 +00:00
|
|
|
"github.com/shirou/gopsutil/cpu"
|
2016-06-11 15:31:49 +00:00
|
|
|
)
|
|
|
|
|
2018-05-08 21:00:31 +00:00
|
|
|
const (
|
2018-05-09 17:21:35 +00:00
|
|
|
// cpuInfoTimeout is the timeout used when gathering CPU info. This is used
|
|
|
|
// to override the default timeout in gopsutil which has a tendency to
|
|
|
|
// timeout on Windows.
|
2018-06-21 19:27:56 +00:00
|
|
|
cpuInfoTimeout = 60 * time.Second
|
2018-05-08 21:00:31 +00:00
|
|
|
)
|
|
|
|
|
2016-06-11 15:31:49 +00:00
|
|
|
var (
|
2016-06-17 19:13:53 +00:00
|
|
|
cpuMhzPerCore float64
|
|
|
|
cpuModelName string
|
|
|
|
cpuNumCores int
|
|
|
|
cpuTotalTicks float64
|
|
|
|
|
2017-03-14 19:56:31 +00:00
|
|
|
initErr error
|
2016-06-17 19:13:53 +00:00
|
|
|
onceLer sync.Once
|
2016-06-10 21:46:33 +00:00
|
|
|
)
|
|
|
|
|
2016-06-17 19:13:53 +00:00
|
|
|
func Init() error {
|
|
|
|
onceLer.Do(func() {
|
2017-06-27 18:54:15 +00:00
|
|
|
var merrs *multierror.Error
|
|
|
|
var err error
|
|
|
|
if cpuNumCores, err = cpu.Counts(true); err != nil {
|
|
|
|
merrs = multierror.Append(merrs, fmt.Errorf("Unable to determine the number of CPU cores available: %v", err))
|
2016-06-17 19:13:53 +00:00
|
|
|
}
|
|
|
|
|
2016-06-11 15:31:49 +00:00
|
|
|
var cpuInfo []cpu.InfoStat
|
2018-05-10 22:52:54 +00:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), cpuInfoTimeout)
|
|
|
|
defer cancel()
|
2018-05-08 21:00:31 +00:00
|
|
|
if cpuInfo, err = cpu.InfoWithContext(ctx); err != nil {
|
2018-05-08 18:11:29 +00:00
|
|
|
merrs = multierror.Append(merrs, fmt.Errorf("Unable to obtain CPU information: %v", err))
|
2016-06-17 19:13:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, cpu := range cpuInfo {
|
|
|
|
cpuModelName = cpu.ModelName
|
|
|
|
cpuMhzPerCore = cpu.Mhz
|
|
|
|
break
|
2016-06-11 15:31:49 +00:00
|
|
|
}
|
2016-06-22 22:01:36 +00:00
|
|
|
|
|
|
|
// Floor all of the values such that small difference don't cause the
|
|
|
|
// node to fall into a unique computed node class
|
|
|
|
cpuMhzPerCore = math.Floor(cpuMhzPerCore)
|
|
|
|
cpuTotalTicks = math.Floor(float64(cpuNumCores) * cpuMhzPerCore)
|
2017-06-27 18:54:15 +00:00
|
|
|
|
|
|
|
// Set any errors that occurred
|
|
|
|
initErr = merrs.ErrorOrNil()
|
2016-06-17 19:13:53 +00:00
|
|
|
})
|
2017-03-14 19:56:31 +00:00
|
|
|
return initErr
|
2016-06-17 19:13:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// CPUModelName returns the number of CPU cores available
|
|
|
|
func CPUNumCores() int {
|
|
|
|
return cpuNumCores
|
|
|
|
}
|
|
|
|
|
|
|
|
// CPUMHzPerCore returns the MHz per CPU core
|
|
|
|
func CPUMHzPerCore() float64 {
|
|
|
|
return cpuMhzPerCore
|
|
|
|
}
|
|
|
|
|
|
|
|
// CPUModelName returns the model name of the CPU
|
|
|
|
func CPUModelName() string {
|
|
|
|
return cpuModelName
|
|
|
|
}
|
|
|
|
|
2017-06-27 18:54:15 +00:00
|
|
|
// TotalTicksAvailable calculates the total Mhz available across all cores
|
2016-06-17 19:13:53 +00:00
|
|
|
func TotalTicksAvailable() float64 {
|
|
|
|
return cpuTotalTicks
|
2016-06-10 21:46:33 +00:00
|
|
|
}
|