Skip to content

Commit

Permalink
split plan 9 codes to internal/procstatus
Browse files Browse the repository at this point in the history
make it testable on other platforms.
  • Loading branch information
koron committed Aug 15, 2020
1 parent c2b0d0a commit 05868fd
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 3 deletions.
63 changes: 63 additions & 0 deletions internal/procstatus/procstatus.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
Package procstatus provides methods to access contents of /proc/{pid}/status
for Plan 9.
*/
package procstatus

import (
"errors"
"fmt"
"io"
"os"
"strconv"
"strings"
)

// GetRSS retrives resident set size (RSS) for a process.
func GetRSS(pid int) (uint, error) {
name := fmt.Sprintf("/proc/%d/status", pid)
r, err := os.Open(name)
if err != nil {
return 0, err
}
defer r.Close()
return readMemSize(r)
}

// readMemSize parses and extracts "amount of memory" (10th entry) from
// /proc/{pid}/status.
func readMemSize(r io.Reader) (uint, error) {
/*
* proc/<n>/status contains process's status separated by a space.
* 1. [27]the process name
* 2. [27]the user name
* 3. [11]the process status
* 4. [11]the time current process has spent in user mode (ms)
* 5. [11]the time current process has spent in system calls (ms)
* 6. [11]the time current process has spent in real elapsed time (ms)
* 7. [11]the time children and descendants's; user mode (ms)
* 8. [11]the time children and descendants's; system calls (ms)
* 9. [11]the time children and descendants's; real elapsed time (ms)
* 10. [11]the amount of memory (kb)
* 11. [11]the base scheduling priority
* 12. [11]the current scheduling priority
*/
const nAllFields = (27+1)*2 + (11+1)*10 // +1: a space
const xAmountOfMemory = (27+1)*2 + (11+1)*7

buf := make([]byte, nAllFields)
n, err := r.Read(buf)
if err != nil {
return 0, fmt.Errorf("failed to read /proc/{pid}/status: %w", err)
}
if n != len(buf) {
return 0, errors.New("insufficient process status")
}
p := xAmountOfMemory
s := strings.TrimSpace(string(buf[p : p+11]))
msize, err := strconv.ParseUint(s, 10, 32)
if err != nil {
return 0, fmt.Errorf("failed to parse 10th field: %w", err)
}
return uint(msize) * 1024, nil
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package phymem
package procstatus

import (
"fmt"
Expand All @@ -12,10 +12,10 @@ func TestReadMemSize(t *testing.T) {
r := strings.NewReader(s)
msize, err := readMemSize(r)
if err != nil {
t.Fatal("readMemSize:", err)
t.Fatal(err)
}
const want = 236 * 1024
if msize != want {
t.Errorf("readMemSize(%q) = %d; want %d", s, msize, want)
t.Errorf("readMemSize failed: want=%d got=%d", want, msize)
}
}
1 change: 1 addition & 0 deletions phymem_plan9.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
// for test.
const providedCurrent = true

// Current get physical memory which used by current process.
func Current() (uint, error) {
name := fmt.Sprintf("/proc/%d/status", os.Getpid())
r, err := os.Open(name)
Expand Down

0 comments on commit 05868fd

Please sign in to comment.