diff options
author | Igor Wiedler <iwiedler@gitlab.com> | 2021-07-05 18:27:14 +0300 |
---|---|---|
committer | Igor Wiedler <iwiedler@gitlab.com> | 2021-07-06 14:00:18 +0300 |
commit | 82065592c3acfb92bef7aaebc8a33c35fbd58114 (patch) | |
tree | b4c1ca7ca57f14ce99efee1bca15f0f4177d674a | |
parent | 893b30557852ec719afed5fb0beccadb40b1dd07 (diff) |
Implement optimized RSS monitor based on /proc/[pid]/statm
The goal of this change is to relieve pressure on forkExec mutex on platforms where this is supported.
Changelog: performance
-rw-r--r-- | internal/ps/ps.go | 10 | ||||
-rw-r--r-- | internal/ps/rss.go | 17 | ||||
-rw-r--r-- | internal/ps/rss_linux.go | 38 |
3 files changed, 55 insertions, 10 deletions
diff --git a/internal/ps/ps.go b/internal/ps/ps.go index 1115547ac..c3613617c 100644 --- a/internal/ps/ps.go +++ b/internal/ps/ps.go @@ -16,16 +16,6 @@ func Exec(pid int, keywords string) (string, error) { return strings.TrimSpace(string(out)), nil } -// RSS invokes ps -o rss= -p pid and returns its output -func RSS(pid int) (int, error) { - rss, err := Exec(pid, "rss=") - if err != nil { - return 0, err - } - - return strconv.Atoi(rss) -} - // Comm invokes ps -o comm= -p pid and returns its output func Comm(pid int) (string, error) { return Exec(pid, "comm=") diff --git a/internal/ps/rss.go b/internal/ps/rss.go new file mode 100644 index 000000000..f6a02abb2 --- /dev/null +++ b/internal/ps/rss.go @@ -0,0 +1,17 @@ +// +build !linux + +package ps + +import ( + "strconv" +) + +// RSS invokes ps -o rss= -p pid and returns its output +func RSS(pid int) (int, error) { + rss, err := Exec(pid, "rss=") + if err != nil { + return 0, err + } + + return strconv.Atoi(rss) +} diff --git a/internal/ps/rss_linux.go b/internal/ps/rss_linux.go new file mode 100644 index 000000000..650fe03a8 --- /dev/null +++ b/internal/ps/rss_linux.go @@ -0,0 +1,38 @@ +package ps + +import ( + "fmt" + "os" +) + +var pageSize = os.Getpagesize() + +// https://gitlab.com/procps-ng/procps/-/blob/37f106029975e3045b0cd779525d14c55d24b74e/proc/readproc.h#L51 +// https://man7.org/linux/man-pages/man5/proc.5.html +type statm struct { + size, resident, shared, text, lib, data, dt int +} + +// RSS returns the RSS of a process, in kB +func RSS(pid int) (int, error) { + file, err := os.Open(fmt.Sprintf("/proc/%d/statm", pid)) + if err != nil { + return 0, err + } + defer file.Close() + + s := statm{} + + // unit for each of these is pages + // https://gitlab.com/procps-ng/procps/-/blob/37f106029975e3045b0cd779525d14c55d24b74e/proc/readproc.c#L660 + _, err = fmt.Fscanf(file, "%d %d %d %d %d %d %d", + &s.size, &s.resident, &s.shared, + &s.text, &s.lib, &s.data, &s.dt) + if err != nil { + return 0, err + } + + rssKbytes := (s.resident * pageSize) / 1024 + + return rssKbytes, nil +} |