github.com/hernad/nomad@v1.6.112/helper/stats/cpu.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package stats
     5  
     6  import (
     7  	"runtime"
     8  	"time"
     9  )
    10  
    11  var (
    12  	cpuTotalTicks uint64
    13  )
    14  
    15  // CpuStats calculates cpu usage percentage
    16  type CpuStats struct {
    17  	prevCpuTime float64
    18  	prevTime    time.Time
    19  
    20  	totalCpus int
    21  }
    22  
    23  // NewCpuStats returns a cpu stats calculator
    24  func NewCpuStats() *CpuStats {
    25  	numCpus := runtime.NumCPU()
    26  	cpuStats := &CpuStats{
    27  		totalCpus: numCpus,
    28  	}
    29  	return cpuStats
    30  }
    31  
    32  // Percent calculates the cpu usage percentage based on the current cpu usage
    33  // and the previous cpu usage where usage is given as time in nanoseconds spend
    34  // in the cpu
    35  func (c *CpuStats) Percent(cpuTime float64) float64 {
    36  	now := time.Now()
    37  
    38  	if c.prevCpuTime == 0.0 {
    39  		// invoked first time
    40  		c.prevCpuTime = cpuTime
    41  		c.prevTime = now
    42  		return 0.0
    43  	}
    44  
    45  	timeDelta := now.Sub(c.prevTime).Nanoseconds()
    46  	ret := c.calculatePercent(c.prevCpuTime, cpuTime, timeDelta)
    47  	c.prevCpuTime = cpuTime
    48  	c.prevTime = now
    49  	return ret
    50  }
    51  
    52  // TicksConsumed calculates the total ticks consumes by the process across all
    53  // cpu cores
    54  func (c *CpuStats) TicksConsumed(percent float64) float64 {
    55  	return (percent / 100) * float64(CpuTotalTicks()) / float64(c.totalCpus)
    56  }
    57  
    58  func (c *CpuStats) calculatePercent(t1, t2 float64, timeDelta int64) float64 {
    59  	vDelta := t2 - t1
    60  	if timeDelta <= 0 || vDelta <= 0.0 {
    61  		return 0.0
    62  	}
    63  
    64  	overall_percent := (vDelta / float64(timeDelta)) * 100.0
    65  	return overall_percent
    66  }
    67  
    68  // Set the total ticks available across all cores.
    69  func SetCpuTotalTicks(newCpuTotalTicks uint64) {
    70  	cpuTotalTicks = newCpuTotalTicks
    71  }
    72  
    73  // CpuTotalTicks calculates the total MHz available across all cores.
    74  //
    75  // Where asymetric cores are correctly detected, the total ticks is the sum of
    76  // the performance across both core types.
    77  //
    78  // Where asymetric cores are not correctly detected (such as Intel 13th gen),
    79  // the total ticks available is over-estimated, as we assume all cores are P
    80  // cores.
    81  func CpuTotalTicks() uint64 {
    82  	return cpuTotalTicks
    83  }