Skip to content

Commit fa0e9fd

Browse files
authoredOct 4, 2017
Merge pull request shirou#428 from Leonid99/threads
Implement Threads() in Linux
2 parents 1873a1f + 7ee4a4c commit fa0e9fd

7 files changed

+64
-17
lines changed
 

‎process/process_darwin.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,8 @@ func (p *Process) NumThreads() (int32, error) {
268268
}
269269
return int32(len(r)), nil
270270
}
271-
func (p *Process) Threads() (map[string]string, error) {
272-
ret := make(map[string]string, 0)
271+
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
272+
ret := make(map[int32]*cpu.TimesStat)
273273
return ret, common.ErrNotImplementedError
274274
}
275275

‎process/process_fallback.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func (p *Process) NumFDs() (int32, error) {
9595
func (p *Process) NumThreads() (int32, error) {
9696
return 0, common.ErrNotImplementedError
9797
}
98-
func (p *Process) Threads() (map[string]string, error) {
98+
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
9999
return nil, common.ErrNotImplementedError
100100
}
101101
func (p *Process) Times() (*cpu.TimesStat, error) {

‎process/process_freebsd.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ func (p *Process) NumThreads() (int32, error) {
204204

205205
return k.Numthreads, nil
206206
}
207-
func (p *Process) Threads() (map[string]string, error) {
208-
ret := make(map[string]string, 0)
207+
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
208+
ret := make(map[int32]*cpu.TimesStat)
209209
return ret, common.ErrNotImplementedError
210210
}
211211
func (p *Process) Times() (*cpu.TimesStat, error) {

‎process/process_linux.go

+35-8
Original file line numberDiff line numberDiff line change
@@ -290,11 +290,23 @@ func (p *Process) NumThreads() (int32, error) {
290290
return p.numThreads, nil
291291
}
292292

293-
// Threads returns a map of threads
294-
//
295-
// Notice: Not implemented yet. always returns empty map.
296-
func (p *Process) Threads() (map[string]string, error) {
297-
ret := make(map[string]string, 0)
293+
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
294+
ret := make(map[int32]*cpu.TimesStat)
295+
taskPath := common.HostProc(strconv.Itoa(int(p.Pid)), "task")
296+
297+
tids, err := readPidsFromDir(taskPath)
298+
if err != nil {
299+
return nil, err
300+
}
301+
302+
for _, tid := range tids {
303+
_, _, cpuTimes, _, _, _, err := p.fillFromTIDStat(tid)
304+
if err != nil {
305+
return nil, err
306+
}
307+
ret[tid] = cpuTimes
308+
}
309+
298310
return ret, nil
299311
}
300312

@@ -922,9 +934,16 @@ func (p *Process) fillFromStatus() error {
922934
return nil
923935
}
924936

925-
func (p *Process) fillFromStat() (string, int32, *cpu.TimesStat, int64, uint32, int32, error) {
937+
func (p *Process) fillFromTIDStat(tid int32) (string, int32, *cpu.TimesStat, int64, uint32, int32, error) {
926938
pid := p.Pid
927-
statPath := common.HostProc(strconv.Itoa(int(pid)), "stat")
939+
var statPath string
940+
941+
if tid == -1 {
942+
statPath = common.HostProc(strconv.Itoa(int(pid)), "stat")
943+
} else {
944+
statPath = common.HostProc(strconv.Itoa(int(pid)), "task", strconv.Itoa(int(tid)), "stat")
945+
}
946+
928947
contents, err := ioutil.ReadFile(statPath)
929948
if err != nil {
930949
return "", 0, nil, 0, 0, 0, err
@@ -989,11 +1008,19 @@ func (p *Process) fillFromStat() (string, int32, *cpu.TimesStat, int64, uint32,
9891008
return terminal, int32(ppid), cpuTimes, createTime, uint32(rtpriority), nice, nil
9901009
}
9911010

1011+
func (p *Process) fillFromStat() (string, int32, *cpu.TimesStat, int64, uint32, int32, error) {
1012+
return p.fillFromTIDStat(-1)
1013+
}
1014+
9921015
// Pids returns a slice of process ID list which are running now.
9931016
func Pids() ([]int32, error) {
1017+
return readPidsFromDir(common.HostProc())
1018+
}
1019+
1020+
func readPidsFromDir(path string) ([]int32, error) {
9941021
var ret []int32
9951022

996-
d, err := os.Open(common.HostProc())
1023+
d, err := os.Open(path)
9971024
if err != nil {
9981025
return nil, err
9991026
}

‎process/process_openbsd.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,8 @@ func (p *Process) NumThreads() (int32, error) {
194194
/* not supported, just return 1 */
195195
return 1, nil
196196
}
197-
func (p *Process) Threads() (map[string]string, error) {
198-
ret := make(map[string]string, 0)
197+
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
198+
ret := make(map[int32]*cpu.TimesStat)
199199
return ret, common.ErrNotImplementedError
200200
}
201201
func (p *Process) Times() (*cpu.TimesStat, error) {

‎process/process_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,26 @@ func Test_Process_NumThread(t *testing.T) {
219219
}
220220
}
221221

222+
func Test_Process_Threads(t *testing.T) {
223+
p := testGetProcess()
224+
225+
n, err := p.NumThreads()
226+
if err != nil {
227+
t.Errorf("geting NumThread error %v", err)
228+
}
229+
if n < 0 {
230+
t.Errorf("invalid NumThread: %d", n)
231+
}
232+
233+
ts, err := p.Threads()
234+
if err != nil {
235+
t.Errorf("geting Threads error %v", err)
236+
}
237+
if len(ts) != int(n) {
238+
t.Errorf("unexpected number of threads: %v vs %v", len(ts), n)
239+
}
240+
}
241+
222242
func Test_Process_Name(t *testing.T) {
223243
p := testGetProcess()
224244

‎process/process_windows.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,8 @@ func (p *Process) NumThreads() (int32, error) {
273273
}
274274
return int32(dst[0].ThreadCount), nil
275275
}
276-
func (p *Process) Threads() (map[string]string, error) {
277-
ret := make(map[string]string, 0)
276+
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
277+
ret := make(map[int32]*cpu.TimesStat)
278278
return ret, common.ErrNotImplementedError
279279
}
280280
func (p *Process) Times() (*cpu.TimesStat, error) {

0 commit comments

Comments
 (0)
Please sign in to comment.