Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Wiedler <iwiedler@gitlab.com>2021-07-05 18:27:14 +0300
committerIgor Wiedler <iwiedler@gitlab.com>2021-07-06 14:00:18 +0300
commit82065592c3acfb92bef7aaebc8a33c35fbd58114 (patch)
treeb4c1ca7ca57f14ce99efee1bca15f0f4177d674a
parent893b30557852ec719afed5fb0beccadb40b1dd07 (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.go10
-rw-r--r--internal/ps/rss.go17
-rw-r--r--internal/ps/rss_linux.go38
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
+}