Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions fixtures.ttar
Original file line number Diff line number Diff line change
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
49 changes: 49 additions & 0 deletions sysfs/system_cpu.go
Original file line number Diff line number Diff line change
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,49 @@ 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, err
}

return parseIsolatedCPUs(isolcpus)
}

func parseIsolatedCPUs(data []byte) ([]uint16, error) {

var isolcpusInt = []uint16{}

for _, cpu := range strings.Split(strings.TrimRight(string(data), "\n"), ",") {
if cpu == "" {
continue
}
if strings.Contains(cpu, "-") {
ranges := strings.Split(cpu, "-")
if len(ranges) != 2 {
return nil, fmt.Errorf("invalid cpu range: %s", cpu)
}
startRange, err := strconv.Atoi(ranges[0])
if err != nil {
return nil, fmt.Errorf("invalid cpu start range: %w", err)
}
endRange, err := strconv.Atoi(ranges[1])
if err != nil {
return nil, fmt.Errorf("invalid cpu end range: %w", err)
}

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

cpuN, err := strconv.Atoi(cpu)
if err != nil {
return nil, err
}
isolcpusInt = append(isolcpusInt, uint16(cpuN))
}
return isolcpusInt, nil
}
52 changes: 52 additions & 0 deletions sysfs/system_cpu_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package sysfs

import (
"errors"
"reflect"
"testing"
)
Expand Down Expand Up @@ -140,3 +141,54 @@ 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},

{[]byte("1,"), []uint16{1}, nil},
{[]byte("1,2-"), nil, errors.New(`invalid cpu end range: strconv.Atoi: parsing "": invalid syntax`)},
{[]byte("1,-3"), nil, errors.New(`invalid cpu start range: strconv.Atoi: parsing "": invalid syntax`)},
}
for _, params := range testParams {
t.Run("blabla", func(t *testing.T) {
res, err := parseIsolatedCPUs(params.in)
if !reflect.DeepEqual(res, params.res) {
t.Fatalf("should have %v result: got %v", params.res, res)
}
if err != nil && params.err != nil && err.Error() != params.err.Error() {
t.Fatalf("should have '%v' error: got '%v'", params.err, err)
}
if (err == nil || params.err == nil) && 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)
}
if err != nil {
t.Errorf("Error not correct: want %v, have %v", nil, err)
}
}