1// package proc contains functionality to read proc status files.
2package proc
3
4import (
5	"strconv"
6	"strings"
7)
8
9// ProcStatus holds information regarding the memory usage of
10// an executing process. The memory sizes in each of the field
11// is in bytes.
12type ProcStatus struct {
13	// Process PID.
14	pid int
15
16	// Peak virtual memory size.
17	VmPeak uint64
18
19	// Virtual memory size.
20	VmSize uint64
21
22	// Locked Memory size.
23	VmLck uint64
24
25	// Pinned memory size.
26	VmPin uint64
27
28	// Peak resident set size.
29	VmHWM uint64
30
31	// Resident set size (sum of RssAnon, RssFile and RssShmem).
32	VmRss uint64
33
34	// Size of resident anonymous memory.
35	RssAnon uint64
36
37	// Size of resident shared memory.
38	RssShmem uint64
39
40	// Size of data segments.
41	VmData uint64
42
43	// Size of stack segments.
44	VmStk uint64
45
46	//Size of text segments.
47	VmExe uint64
48
49	//Shared library code size.
50	VmLib uint64
51
52	// Page table entries size.
53	VmPTE uint64
54
55	// Size of second-level page tables.
56	VmPMD uint64
57
58	// Swapped-out virtual memory size by anonymous private.
59	VmSwap uint64
60
61	// Size of hugetlb memory page size.
62	HugetlbPages uint64
63}
64
65// fillProcStatus takes the key and value, converts the value
66// to the proper size unit and is stored in the ProcStatus.
67func fillProcStatus(s *ProcStatus, key, value string) {
68	v := strToUint64(value)
69	switch key {
70	case "VmPeak":
71		s.VmPeak = v
72	case "VmSize":
73		s.VmSize = v
74	case "VmLck":
75		s.VmLck = v
76	case "VmPin":
77		s.VmPin = v
78	case "VmHWM":
79		s.VmHWM = v
80	case "VmRSS":
81		s.VmRss = v
82	case "RssAnon":
83		s.RssAnon = v
84	case "RssShmem":
85		s.RssShmem = v
86	case "VmData":
87		s.VmData = v
88	case "VmStk":
89		s.VmStk = v
90	case "VmExe":
91		s.VmExe = v
92	case "VmLib":
93		s.VmLib = v
94	case "VmPTE":
95		s.VmPTE = v
96	case "VmPMD":
97		s.VmPMD = v
98	case "VmSwap":
99		s.VmSwap = v
100	case "HugetlbPages":
101		s.HugetlbPages = v
102	}
103}
104
105// strToUint64 takes the string and converts to unsigned 64-bit integer.
106// If the string contains a memory unit such as kB and is converted to
107// bytes.
108func strToUint64(v string) uint64 {
109	// v could be "1024 kB" so scan for the empty space and
110	// split between the value and the unit.
111	var separatorIndex int
112	if separatorIndex = strings.IndexAny(v, " "); separatorIndex < 0 {
113		separatorIndex = len(v)
114	}
115	value, err := strconv.ParseUint(v[:separatorIndex], 10, 64)
116	if err != nil {
117		return 0
118	}
119
120	var scale uint64 = 1
121	switch strings.TrimSpace(v[separatorIndex:]) {
122	case "kB", "KB":
123		scale = 1024
124	case "mB", "MB":
125		scale = 1024 * 1024
126	}
127	return value * scale
128}
129