MCPcopy
hub / github.com/jaypipes/ghw / logicalProcessorsFromProcCPUInfo

Function logicalProcessorsFromProcCPUInfo

pkg/cpu/cpu_linux.go:350–409  ·  view source on GitHub ↗

logicalProcessorsFromProcCPUInfo reads the `/proc/cpuinfo` pseudofile and returns a map, keyed by logical processor ID, of logical processor structs. `/proc/cpuinfo` files look like the following: ``` processor : 0 vendor_id : AuthenticAMD cpu family : 23 model : 8 model name : AMD Ryzen 7 2700X

(
	ctx context.Context,
)

Source from the content-addressed store, hash-verified

348// with blank line-separated blocks of colon-delimited attribute name/value
349// pairs for a specific logical processor on the host.
350func logicalProcessorsFromProcCPUInfo(
351 ctx context.Context,
352) map[int]*logicalProcessor {
353 paths := linuxpath.New(ctx)
354 r, err := os.Open(paths.ProcCpuinfo)
355 if err != nil {
356 return nil
357 }
358 defer util.SafeClose(r)
359
360 lps := map[int]*logicalProcessor{}
361
362 // A map of attributes describing the logical processor
363 lpAttrs := map[string]string{}
364
365 scanner := bufio.NewScanner(r)
366 for scanner.Scan() {
367 line := strings.TrimSpace(scanner.Text())
368 if line == "" {
369 // Output of /proc/cpuinfo has a blank newline to separate logical
370 // processors, so here we collect up all the attributes we've
371 // collected for this logical processor block
372 // s390x identifies CPUs via "cpu number", while most other
373 // architectures use "processor".
374 idStr, ok := lpAttrs["processor"]
375 if !ok {
376 idStr, ok = lpAttrs["cpu number"]
377 }
378
379 if ok {
380 id, _ := strconv.Atoi(idStr)
381 lps[id] = &logicalProcessor{
382 ID: id,
383 Attrs: lpAttrs,
384 }
385 // Only reset attributes after a valid processor block is saved.
386 // This ensures that shared header metadata (like vendor_id on s390x)
387 // is carried over and available to the processor entries.
388 lpAttrs = map[string]string{}
389 } else if len(lpAttrs) > 0 {
390 // s390x header check: if we have 'vendor_id' but no 'processor' ID,
391 // it's the summary block. We don't warn and we don't reset lpAttrs
392 // so the vendor_id carries over to the first actual CPU block.
393 if _, isS390Header := lpAttrs["vendor_id"]; !isS390Header {
394 log.Warn(ctx,
395 "expected to find 'processor' or 'cpu number' key "+
396 "in /proc/cpuinfo attributes")
397 }
398 }
399 continue
400 }
401 parts := strings.SplitN(line, ":", 2)
402 if len(parts) >= 2 {
403 key := strings.TrimSpace(parts[0])
404 value := strings.TrimSpace(parts[1])
405 lpAttrs[key] = value
406 }
407 }

Callers 1

processorsGetFunction · 0.85

Calls 3

NewFunction · 0.92
SafeCloseFunction · 0.92
WarnFunction · 0.92

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…