Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add isolated cpu parsing #427

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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) {
DavidVentura marked this conversation as resolved.
Show resolved Hide resolved
isolcpus_str := strings.TrimRight(string(data), "\n")
DavidVentura marked this conversation as resolved.
Show resolved Hide resolved

var isolcpus_int = []uint16{}

for _, cpu := range strings.Split(isolcpus_str, ",") {
DavidVentura marked this conversation as resolved.
Show resolved Hide resolved
if cpu == "" {
continue
}
if strings.Contains(cpu, "-") {
ranges := strings.Split(cpu, "-")
DavidVentura marked this conversation as resolved.
Show resolved Hide resolved
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)
DavidVentura marked this conversation as resolved.
Show resolved Hide resolved
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},
DavidVentura marked this conversation as resolved.
Show resolved Hide resolved
}
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)
}
}