github.com/manicqin/nomad@v0.9.5/helper/stats/cpu.go (about)

     1  package stats
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"math"
     7  	"sync"
     8  	"time"
     9  
    10  	multierror "github.com/hashicorp/go-multierror"
    11  	"github.com/shirou/gopsutil/cpu"
    12  )
    13  
    14  const (
    15  	// cpuInfoTimeout is the timeout used when gathering CPU info. This is used
    16  	// to override the default timeout in gopsutil which has a tendency to
    17  	// timeout on Windows.
    18  	cpuInfoTimeout = 60 * time.Second
    19  )
    20  
    21  var (
    22  	cpuMhzPerCore float64
    23  	cpuModelName  string
    24  	cpuNumCores   int
    25  	cpuTotalTicks float64
    26  
    27  	initErr error
    28  	onceLer sync.Once
    29  )
    30  
    31  func Init() error {
    32  	onceLer.Do(func() {
    33  		var merrs *multierror.Error
    34  		var err error
    35  		if cpuNumCores, err = cpu.Counts(true); err != nil {
    36  			merrs = multierror.Append(merrs, fmt.Errorf("Unable to determine the number of CPU cores available: %v", err))
    37  		}
    38  
    39  		var cpuInfo []cpu.InfoStat
    40  		ctx, cancel := context.WithTimeout(context.Background(), cpuInfoTimeout)
    41  		defer cancel()
    42  		if cpuInfo, err = cpu.InfoWithContext(ctx); err != nil {
    43  			merrs = multierror.Append(merrs, fmt.Errorf("Unable to obtain CPU information: %v", err))
    44  		}
    45  
    46  		for _, cpu := range cpuInfo {
    47  			cpuModelName = cpu.ModelName
    48  			cpuMhzPerCore = cpu.Mhz
    49  			break
    50  		}
    51  
    52  		// Floor all of the values such that small difference don't cause the
    53  		// node to fall into a unique computed node class
    54  		cpuMhzPerCore = math.Floor(cpuMhzPerCore)
    55  		cpuTotalTicks = math.Floor(float64(cpuNumCores) * cpuMhzPerCore)
    56  
    57  		// Set any errors that occurred
    58  		initErr = merrs.ErrorOrNil()
    59  	})
    60  	return initErr
    61  }
    62  
    63  // CPUModelName returns the number of CPU cores available
    64  func CPUNumCores() int {
    65  	return cpuNumCores
    66  }
    67  
    68  // CPUMHzPerCore returns the MHz per CPU core
    69  func CPUMHzPerCore() float64 {
    70  	return cpuMhzPerCore
    71  }
    72  
    73  // CPUModelName returns the model name of the CPU
    74  func CPUModelName() string {
    75  	return cpuModelName
    76  }
    77  
    78  // TotalTicksAvailable calculates the total Mhz available across all cores
    79  func TotalTicksAvailable() float64 {
    80  	return cpuTotalTicks
    81  }