#include <malloc.h>
#endif
-#include <fstream>
+#include <charconv>
+
+#include "common/fmt_common.h"
+
#define dout_subsys ceph_subsys_
{
}
-void MemoryModel::_sample(mem_snap_t *psnap)
+std::optional<int64_t> MemoryModel::get_mapped_heap()
{
- ifstream f;
-
- f.open(PROCPREFIX "/proc/self/status");
- if (!f.is_open()) {
- ldout(cct, 0) << "check_memory_usage unable to open " PROCPREFIX "/proc/self/status" << dendl;
- return;
+ if (!proc_maps.is_open()) {
+ ldout(cct, 0) << fmt::format("MemoryModel::get_mapped_heap() unable to open {}", proc_maps_fn) << dendl;
+ return std::nullopt;
}
- while (!f.eof()) {
- string line;
- getline(f, line);
-
- if (strncmp(line.c_str(), "VmSize:", 7) == 0)
- psnap->size = atol(line.c_str() + 7);
- else if (strncmp(line.c_str(), "VmRSS:", 6) == 0)
- psnap->rss = atol(line.c_str() + 7);
- else if (strncmp(line.c_str(), "VmHWM:", 6) == 0)
- psnap->hwm = atol(line.c_str() + 7);
- else if (strncmp(line.c_str(), "VmLib:", 6) == 0)
- psnap->lib = atol(line.c_str() + 7);
- else if (strncmp(line.c_str(), "VmPeak:", 7) == 0)
- psnap->peak = atol(line.c_str() + 7);
- else if (strncmp(line.c_str(), "VmData:", 7) == 0)
- psnap->data = atol(line.c_str() + 7);
- }
- f.close();
+ // always rewind before reading
+ proc_maps.clear();
+ proc_maps.seekg(0);
- f.open(PROCPREFIX "/proc/self/maps");
- if (!f.is_open()) {
- ldout(cct, 0) << "check_memory_usage unable to open " PROCPREFIX "/proc/self/maps" << dendl;
- return;
- }
+ int64_t heap = 0;
- long heap = 0;
- while (f.is_open() && !f.eof()) {
+ while (proc_maps.is_open() && !proc_maps.eof()) {
string line;
- getline(f, line);
- //ldout(cct, 0) << "line is " << line << dendl;
+ getline(proc_maps, line);
const char *start = line.c_str();
const char *dash = start;
unsigned long long as = strtoll(start, 0, 16);
unsigned long long ae = strtoll(dash+1, 0, 16);
- //ldout(cct, 0) << std::hex << as << " to " << ae << std::dec << dendl;
-
end++;
const char *mode = end;
end++;
long size = ae - as;
- //ldout(cct, 0) << "size " << size << " mode is '" << mode << "' end is '" << end << "'" << dendl;
/*
* anything 'rw' and anon is assumed to be heap.
heap += size;
}
- psnap->heap = heap >> 10;
+ return heap;
+}
+
+
+
+void MemoryModel::_sample(mem_snap_t *psnap)
+{
+ if (!proc_status.is_open()) {
+ ldout(cct, 0) << fmt::format("MemoryModel::sample() unable to open {}", proc_stat_fn) << dendl;
+ return;
+ }
+ // always rewind before reading
+ proc_status.clear();
+ proc_status.seekg(0);
+
+ while (!proc_status.eof()) {
+ string line;
+ getline(proc_status, line);
+
+ if (strncmp(line.c_str(), "VmSize:", 7) == 0)
+ psnap->size = atol(line.c_str() + 7);
+ else if (strncmp(line.c_str(), "VmRSS:", 6) == 0)
+ psnap->rss = atol(line.c_str() + 7);
+ else if (strncmp(line.c_str(), "VmHWM:", 6) == 0)
+ psnap->hwm = atol(line.c_str() + 7);
+ else if (strncmp(line.c_str(), "VmLib:", 6) == 0)
+ psnap->lib = atol(line.c_str() + 7);
+ else if (strncmp(line.c_str(), "VmPeak:", 7) == 0)
+ psnap->peak = atol(line.c_str() + 7);
+ else if (strncmp(line.c_str(), "VmData:", 7) == 0)
+ psnap->data = atol(line.c_str() + 7);
+ }
+ // get heap size
+ psnap->heap = static_cast<long>(get_mapped_heap().value_or(0));
}