github.com/jaypipes/ghw@v0.21.1/pkg/cpu/cpu.go (about)

     1  //
     2  // Use and distribution licensed under the Apache license version 2.
     3  //
     4  // See the COPYING file in the root project directory for full text.
     5  //
     6  
     7  package cpu
     8  
     9  import (
    10  	"fmt"
    11  
    12  	"github.com/jaypipes/ghw/pkg/context"
    13  	"github.com/jaypipes/ghw/pkg/marshal"
    14  	"github.com/jaypipes/ghw/pkg/option"
    15  )
    16  
    17  // ProcessorCore describes a physical host processor core. A processor core is
    18  // a separate processing unit within some types of central processing units
    19  // (CPU).
    20  type ProcessorCore struct {
    21  	// ID is the `uint32` identifier that the host gave this core. Note that
    22  	// this does *not* necessarily equate to a zero-based index of the core
    23  	// within a physical package. For example, the core IDs for an Intel Core
    24  	// i7 are 0, 1, 2, 8, 9, and 10
    25  	ID int `json:"id"`
    26  	// TotalHardwareThreads is the number of hardware threads associated with
    27  	// the core
    28  	TotalHardwareThreads uint32 `json:"total_hardware_threads"`
    29  	// NumThreads is the number of hardware threads associated with the core.
    30  	// DEPRECATED: Use `TotalHardwareThreads` instead.
    31  	NumThreads uint32 `json:"total_threads"`
    32  	// LogicalProcessors is a slice of ints representing the logical processor
    33  	// IDs assigned to any processing unit for the core. These are sometimes
    34  	// called the "thread siblings". Logical processor IDs are the *zero-based*
    35  	// index of the processor on the host and are *not* related to the core ID.
    36  	LogicalProcessors []int `json:"logical_processors"`
    37  }
    38  
    39  // String returns a short string indicating important information about the
    40  // processor core
    41  func (c *ProcessorCore) String() string {
    42  	return fmt.Sprintf(
    43  		"processor core #%d (%d threads), logical processors %v",
    44  		c.ID,
    45  		c.TotalHardwareThreads,
    46  		c.LogicalProcessors,
    47  	)
    48  }
    49  
    50  // Processor describes a physical host central processing unit (CPU).
    51  type Processor struct {
    52  	// ID is the physical processor `uint32` ID according to the system
    53  	ID int `json:"id"`
    54  	// TotalCores is the number of physical cores in the processor package
    55  	TotalCores uint32 `json:"total_cores"`
    56  	// NumCores is the number of physical cores in the processor package
    57  	// DEPRECATED: Use `TotalCores` instead.
    58  	NumCores uint32 `json:"-"`
    59  	// TotalHardwareThreads is the number of hardware threads associated with
    60  	// the processor package
    61  	TotalHardwareThreads uint32 `json:"total_hardware_threads"`
    62  	// NumThreads is the number of hardware threads in the processor package
    63  	// DEPRECATED: Use `TotalHardwareThreads` instead.
    64  	NumThreads uint32 `json:"total_threads"`
    65  	// Vendor is a string containing the vendor name
    66  	Vendor string `json:"vendor"`
    67  	// Model` is a string containing the vendor's model name
    68  	Model string `json:"model"`
    69  	// Capabilities is a slice of strings indicating the features the processor
    70  	// has enabled
    71  	Capabilities []string `json:"capabilities"`
    72  	// Cores is a slice of ProcessorCore` struct pointers that are packed onto
    73  	// this physical processor
    74  	Cores []*ProcessorCore `json:"cores"`
    75  }
    76  
    77  // CoreByID returns the ProcessorCore having the supplied ID.
    78  func (p *Processor) CoreByID(coreID int) *ProcessorCore {
    79  	for _, core := range p.Cores {
    80  		if core.ID == coreID {
    81  			return core
    82  		}
    83  	}
    84  	return nil
    85  }
    86  
    87  // HasCapability returns true if the Processor has the supplied cpuid
    88  // capability, false otherwise. Example of cpuid capabilities would be 'vmx' or
    89  // 'sse4_2'. To see a list of potential cpuid capabilitiies, see the section on
    90  // CPUID feature bits in the following article:
    91  //
    92  // https://en.wikipedia.org/wiki/CPUID
    93  func (p *Processor) HasCapability(find string) bool {
    94  	for _, c := range p.Capabilities {
    95  		if c == find {
    96  			return true
    97  		}
    98  	}
    99  	return false
   100  }
   101  
   102  // String returns a short string describing the Processor
   103  func (p *Processor) String() string {
   104  	ncs := "cores"
   105  	if p.TotalCores == 1 {
   106  		ncs = "core"
   107  	}
   108  	nts := "threads"
   109  	if p.TotalHardwareThreads == 1 {
   110  		nts = "thread"
   111  	}
   112  	return fmt.Sprintf(
   113  		"physical package #%d (%d %s, %d hardware %s)",
   114  		p.ID,
   115  		p.TotalCores,
   116  		ncs,
   117  		p.TotalHardwareThreads,
   118  		nts,
   119  	)
   120  }
   121  
   122  // Info describes all central processing unit (CPU) functionality on a host.
   123  // Returned by the `ghw.CPU()` function.
   124  type Info struct {
   125  	ctx *context.Context
   126  	// TotalCores is the total number of physical cores the host system
   127  	// contains
   128  	TotalCores uint32 `json:"total_cores"`
   129  	// TotalThreads is the total number of hardware threads the host system
   130  	// contains
   131  	TotalHardwareThreads uint32 `json:"total_hardware_threads"`
   132  	// TotalThreads is the total number of hardware threads the host system
   133  	// contains
   134  	// DEPRECATED: Use `TotalHardwareThreads` instead
   135  	TotalThreads uint32 `json:"total_threads"`
   136  	// Processors is a slice of Processor struct pointers, one for each
   137  	// physical processor package contained in the host
   138  	Processors []*Processor `json:"processors"`
   139  }
   140  
   141  // New returns a pointer to an Info struct that contains information about the
   142  // CPUs on the host system
   143  func New(opts ...*option.Option) (*Info, error) {
   144  	ctx := context.New(opts...)
   145  	info := &Info{ctx: ctx}
   146  	if err := ctx.Do(info.load); err != nil {
   147  		return nil, err
   148  	}
   149  	return info, nil
   150  }
   151  
   152  // String returns a short string indicating a summary of CPU information
   153  func (i *Info) String() string {
   154  	nps := "packages"
   155  	if len(i.Processors) == 1 {
   156  		nps = "package"
   157  	}
   158  	ncs := "cores"
   159  	if i.TotalCores == 1 {
   160  		ncs = "core"
   161  	}
   162  	nts := "threads"
   163  	if i.TotalThreads == 1 {
   164  		nts = "thread"
   165  	}
   166  	return fmt.Sprintf(
   167  		"cpu (%d physical %s, %d %s, %d hardware %s)",
   168  		len(i.Processors),
   169  		nps,
   170  		i.TotalCores,
   171  		ncs,
   172  		i.TotalThreads,
   173  		nts,
   174  	)
   175  }
   176  
   177  // simple private struct used to encapsulate cpu information in a top-level
   178  // "cpu" YAML/JSON map/object key
   179  type cpuPrinter struct {
   180  	Info *Info `json:"cpu"`
   181  }
   182  
   183  // YAMLString returns a string with the cpu information formatted as YAML
   184  // under a top-level "cpu:" key
   185  func (i *Info) YAMLString() string {
   186  	return marshal.SafeYAML(i.ctx, cpuPrinter{i})
   187  }
   188  
   189  // JSONString returns a string with the cpu information formatted as JSON
   190  // under a top-level "cpu:" key
   191  func (i *Info) JSONString(indent bool) string {
   192  	return marshal.SafeJSON(i.ctx, cpuPrinter{i}, indent)
   193  }