-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlinux_proc_tools.cpp
More file actions
120 lines (110 loc) · 3.43 KB
/
Copy pathlinux_proc_tools.cpp
File metadata and controls
120 lines (110 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "linux_proc_tools.hpp"
#include <algorithm>
#include <cstdint>
#include <filesystem>
#include <format>
#include <fstream>
#include <iostream>
#include <numeric>
#include <sstream>
#include <string>
#include <vector>
#include "functions.hpp"
namespace tsp {
uint64_t parse_smaps_line(std::string line) {
auto second_field_start = line.find(":") + 1;
auto second_field_end = line.find("k", second_field_start) - 1;
return std::stoull(
line.substr(second_field_start, second_field_end - second_field_start));
}
void parse_smaps(pid_t pid, mem_data &data) {
auto smaps_file_path = std::format("/proc/{}/smaps_rollup", pid);
std::ifstream smaps_file(smaps_file_path);
std::string line;
if (smaps_file.is_open()) {
while (std::getline(smaps_file, line)) {
if (line.starts_with("Rss:")) {
data.rss += parse_smaps_line(line);
}
if (line.starts_with("Pss:")) {
data.pss += parse_smaps_line(line);
}
if (line.starts_with("Shared_Clean:")) {
data.shared += parse_smaps_line(line);
}
if (line.starts_with("Shared_Dirty:")) {
data.shared += parse_smaps_line(line);
}
if (line.starts_with("Swap:")) {
data.swap += parse_smaps_line(line);
}
if (line.starts_with("SwapPss:")) {
data.swap_pss += parse_smaps_line(line);
}
}
}
return;
}
std::pair<pid_t, uint64_t> get_ppid_and_vmem(std::string stat_line) {
// ppid is the 4th entry in the stat file
std::pair<pid_t, uint64_t> out;
std::string seg;
std::stringstream ss(stat_line);
for (int i = 0; i <= STAT_VSZ_FIELD; ++i) {
std::getline(ss, seg, ' ');
if (i == STAT_PPID_FIELD) {
try {
out.first = static_cast<pid_t>(std::stol(seg));
} catch (const std::exception &e) {
std::cerr << e.what() << '\n'
<< "Error reading ppid" << seg << " from " << stat_line
<< " from /proc/<pid>/stat" << std::endl;
return {-1, 0};
}
}
}
try {
out.second = std::stoull(seg);
} catch (const std::exception &e) {
std::cerr << e.what() << '\n'
<< "Error reading vmem" << seg << " from " << stat_line
<< " from /proc/<pid>/stat" << std::endl;
return {-1, 0};
}
return out;
}
pid_map_t get_pid_map() {
pid_map_t out;
std::vector<std::string> exclude{{"self"}, {"thread-self"}};
std::string line;
for (auto const &dirent : std::filesystem::directory_iterator("/proc")) {
if (dirent.is_directory()) {
if (std::find(exclude.begin(), exclude.end(),
dirent.path().filename().string()) != exclude.end()) {
continue;
}
auto stat_file_path = dirent.path() / "stat";
if (std::filesystem::is_regular_file(stat_file_path)) {
pid_t pid;
try {
pid = std::stol(dirent.path().filename().string());
} catch (const std::exception &e) {
std::cerr << e.what() << '\n'
<< "Looks like " << dirent.path().filename()
<< "needs to be added to the /proc path exclusions list"
<< std::endl;
}
std::ifstream stat_file(stat_file_path);
if (stat_file.is_open()) {
std::getline(stat_file, line);
auto ppid = get_ppid_and_vmem(line);
if (ppid.first != -1) {
out[ppid.first].push_back({pid, ppid.second});
}
}
}
}
}
return out;
}
} // namespace tsp