Skip to content

Commit

Permalink
Add isolated cpu parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidVentura committed Dec 15, 2021
1 parent 5bd7067 commit 1c26c97
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 0 deletions.
5 changes: 5 additions & 0 deletions fixtures.ttar
Expand Up @@ -6462,6 +6462,11 @@ Mode: 644
Directory: fixtures/sys/devices/system/cpu/cpufreq/policy1
Mode: 755
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/sys/devices/system/cpu/isolated
Lines: 1
1,2-7,9
Mode: 664
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/sys/devices/system/node
Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expand Down
47 changes: 47 additions & 0 deletions sysfs/system_cpu.go
Expand Up @@ -16,8 +16,11 @@
package sysfs

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"

"golang.org/x/sync/errgroup"
Expand Down Expand Up @@ -237,3 +240,47 @@ func parseCpufreqCpuinfo(cpuPath string) (*SystemCPUCpufreqStats, error) {
SetSpeed: stringOut[4],
}, nil
}

func (fs FS) IsolatedCPUs() ([]uint16, error) {
isolcpus, err := ioutil.ReadFile(fs.sys.Path("devices/system/cpu/isolated"))
if err != nil {
return nil, fmt.Errorf("failed to read isolcpus from sysfs: %w", err)
}

return parseIsolCpus(isolcpus)
}

func parseIsolCpus(data []byte) ([]uint16, error) {
isolcpus_str := strings.TrimRight(string(data), "\n")

var isolcpus_int = []uint16{}

for _, cpu := range strings.Split(isolcpus_str, ",") {
if cpu == "" {
continue
}
if strings.Contains(cpu, "-") {
ranges := strings.Split(cpu, "-")
startRange, err := strconv.Atoi(ranges[0])
if err != nil {
return nil, err
}
endRange, err := strconv.Atoi(ranges[1])
if err != nil {
return nil, err
}

for i := startRange; i <= endRange; i++ {
isolcpus_int = append(isolcpus_int, uint16(i))
}
continue
}

_cpu, err := strconv.Atoi(cpu)
if err != nil {
return nil, err
}
isolcpus_int = append(isolcpus_int, uint16(_cpu))
}
return isolcpus_int, nil
}
40 changes: 40 additions & 0 deletions sysfs/system_cpu_test.go
Expand Up @@ -140,3 +140,43 @@ func TestSystemCpufreq(t *testing.T) {
t.Errorf("Result not correct: want %v, have %v", systemCpufreq, c)
}
}

func TestIsolatedParsingCPU(t *testing.T) {
var testParams = []struct {
in []byte
res []uint16
err error
}{
{[]byte(""), []uint16{}, nil},
{[]byte("1\n"), []uint16{1}, nil},
{[]byte("1"), []uint16{1}, nil},
{[]byte("1,2"), []uint16{1, 2}, nil},
{[]byte("1-2"), []uint16{1, 2}, nil},
{[]byte("1-3"), []uint16{1, 2, 3}, nil},
{[]byte("1,2-4"), []uint16{1, 2, 3, 4}, nil},
{[]byte("1,3-4"), []uint16{1, 3, 4}, nil},
{[]byte("1,3-4,7,20-21"), []uint16{1, 3, 4, 7, 20, 21}, nil},
}
for _, params := range testParams {
t.Run("blabla", func(t *testing.T) {
res, err := parseIsolCpus(params.in)
if !reflect.DeepEqual(res, params.res) {
t.Fatalf("should have %v result: got %v", params.res, res)
}
if err != params.err {
t.Fatalf("should have %v error: got %v", params.err, err)
}
})
}
}
func TestIsolatedCPUs(t *testing.T) {
fs, err := NewFS(sysTestFixtures)
if err != nil {
t.Fatal(err)
}
isolated, err := fs.IsolatedCPUs()
expected := []uint16{1, 2, 3, 4, 5, 6, 7, 9}
if !reflect.DeepEqual(isolated, expected) {
t.Errorf("Result not correct: want %v, have %v", expected, isolated)
}
}

0 comments on commit 1c26c97

Please sign in to comment.