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 }