Lookup all information from /sys/devices/system/cpu, /proc/cpuinfo is not portable

This commit is contained in:
Holger Obermaier 2023-09-08 10:09:04 +02:00
parent fd56a14eb6
commit e5173bb9a2

View File

@ -1,7 +1,6 @@
package ccTopology package ccTopology
import ( import (
"bufio"
"fmt" "fmt"
"log" "log"
"os" "os"
@ -14,11 +13,7 @@ import (
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
) )
const ( const SYSFS_CPUBASE = `/sys/devices/system/cpu`
SYSFS_NUMABASE = `/sys/devices/system/node`
SYSFS_CPUBASE = `/sys/devices/system/cpu`
PROCFS_CPUINFO = `/proc/cpuinfo`
)
// Structure holding all information about a hardware thread // Structure holding all information about a hardware thread
type HwthreadEntry struct { type HwthreadEntry struct {
@ -43,36 +38,42 @@ var cache struct {
// init initializes the cache structure // init initializes the cache structure
func init() { func init() {
file, err := os.Open(PROCFS_CPUINFO)
if err != nil {
log.Print(err)
return
}
defer file.Close()
scanner := bufio.NewScanner(file) getHWThreads :=
for scanner.Scan() { func() []int {
lineSplit := strings.Split(scanner.Text(), ":") globPath := filepath.Join(SYSFS_CPUBASE, "cpu[0-9]*")
if len(lineSplit) == 2 { regexPath := filepath.Join(SYSFS_CPUBASE, "cpu([[:digit:]]+)")
key := strings.TrimSpace(lineSplit[0]) regex := regexp.MustCompile(regexPath)
value := strings.TrimSpace(lineSplit[1])
switch key { // File globbing for hardware threads
case "physical id": files, err := filepath.Glob(globPath)
id, err := strconv.Atoi(value)
if err != nil { if err != nil {
log.Print(err) cclogger.ComponentError("CCTopology", "init:getHWThreads", err.Error())
return return nil
} }
cache.SocketList = append(cache.SocketList, id)
case "processor": hwThreadIDs := make([]int, len(files))
id, err := strconv.Atoi(value) for i, file := range files {
// Extract hardware thread ID
matches := regex.FindStringSubmatch(file)
if len(matches) != 2 {
cclogger.ComponentError("CCTopology", "init:getHWThreads: Failed to extract hardware thread ID from ", file)
return nil
}
// Convert hardware thread ID to int
id, err := strconv.Atoi(matches[1])
if err != nil { if err != nil {
log.Print(err) cclogger.ComponentError("CCTopology", "init:getHWThreads: Failed to convert to int hardware thread ID ", matches[1])
return return nil
}
cache.HwthreadList = append(cache.HwthreadList, id)
} }
hwThreadIDs[i] = id
} }
// Sort hardware thread IDs
slices.Sort(hwThreadIDs)
return hwThreadIDs
} }
getSMT := getSMT :=
@ -127,7 +128,9 @@ func init() {
return id return id
} }
cache.HwthreadList = getHWThreads()
cache.CoreList = make([]int, len(cache.HwthreadList)) cache.CoreList = make([]int, len(cache.HwthreadList))
cache.SocketList = make([]int, len(cache.HwthreadList))
cache.DieList = make([]int, len(cache.HwthreadList)) cache.DieList = make([]int, len(cache.HwthreadList))
cache.SMTList = make([]int, len(cache.HwthreadList)) cache.SMTList = make([]int, len(cache.HwthreadList))
cache.NumaDomainList = make([]int, len(cache.HwthreadList)) cache.NumaDomainList = make([]int, len(cache.HwthreadList))
@ -135,7 +138,7 @@ func init() {
// Set base directory for topology lookup // Set base directory for topology lookup
base := base :=
filepath.Join( filepath.Join(
"/sys/devices/system/cpu", SYSFS_CPUBASE,
fmt.Sprintf("cpu%d", c), fmt.Sprintf("cpu%d", c),
) )
topoBase := filepath.Join(base, "topology") topoBase := filepath.Join(base, "topology")
@ -143,6 +146,9 @@ func init() {
// Lookup Core ID // Lookup Core ID
cache.CoreList[i] = fileToInt(filepath.Join(topoBase, "core_id")) cache.CoreList[i] = fileToInt(filepath.Join(topoBase, "core_id"))
// Lookup socket / physical package ID
cache.SocketList[i] = fileToInt(filepath.Join(topoBase, "physical_package_id"))
// Lookup CPU die id // Lookup CPU die id
cache.DieList[i] = fileToInt(filepath.Join(topoBase, "die_id")) cache.DieList[i] = fileToInt(filepath.Join(topoBase, "die_id"))
if cache.DieList[i] < 0 { if cache.DieList[i] < 0 {