cpu.go 4.9 KB

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