diff --git a/proc_status.go b/proc_status.go index 3d8c0643..c055d075 100644 --- a/proc_status.go +++ b/proc_status.go @@ -15,6 +15,7 @@ package procfs import ( "bytes" + "sort" "strconv" "strings" @@ -76,6 +77,9 @@ type ProcStatus struct { UIDs [4]string // GIDs of the process (Real, effective, saved set, and filesystem GIDs) GIDs [4]string + + // CpusAllowedList: List of cpu cores processes are allowed to run on. + CpusAllowedList []uint64 } // NewStatus returns the current status information of the process. @@ -161,10 +165,38 @@ func (s *ProcStatus) fillStatus(k string, vString string, vUint uint64, vUintByt s.VoluntaryCtxtSwitches = vUint case "nonvoluntary_ctxt_switches": s.NonVoluntaryCtxtSwitches = vUint + case "Cpus_allowed_list": + s.CpusAllowedList = calcCpusAllowedList(vString) } + } // TotalCtxtSwitches returns the total context switch. func (s ProcStatus) TotalCtxtSwitches() uint64 { return s.VoluntaryCtxtSwitches + s.NonVoluntaryCtxtSwitches } + +func calcCpusAllowedList(cpuString string) []uint64 { + s := strings.Split(cpuString, ",") + + var g []uint64 + + for _, cpu := range s { + // parse cpu ranges, example: 1-3=[1,2,3] + if l := strings.Split(strings.TrimSpace(cpu), "-"); len(l) > 1 { + startCPU, _ := strconv.ParseUint(l[0], 10, 64) + endCPU, _ := strconv.ParseUint(l[1], 10, 64) + + for i := startCPU; i <= endCPU; i++ { + g = append(g, i) + } + } else if len(l) == 1 { + cpu, _ := strconv.ParseUint(l[0], 10, 64) + g = append(g, cpu) + } + + } + + sort.Slice(g, func(i, j int) bool { return g[i] < g[j] }) + return g +} diff --git a/proc_status_test.go b/proc_status_test.go index 3c9ab598..2f0884ff 100644 --- a/proc_status_test.go +++ b/proc_status_test.go @@ -14,6 +14,7 @@ package procfs import ( + "reflect" "testing" ) @@ -121,3 +122,19 @@ func TestProcStatusGIDs(t *testing.T) { t.Errorf("want uids %s, have %s", want, have) } } + +func TestCpusAllowedList(t *testing.T) { + p, err := getProcFixtures(t).Proc(26231) + if err != nil { + t.Fatal(err) + } + + s, err := p.NewStatus() + if err != nil { + t.Fatal(err) + } + + if want, have := []uint64{0, 1, 2, 3, 4, 5, 6, 7}, s.CpusAllowedList; !reflect.DeepEqual(want, have) { + t.Errorf("want CpusAllowedList %v, have %v", want, have) + } +}