NS_DECL_THREADSAFE_ISUPPORTS #define REPORT_WITH_CLEANUP(_path, _units, _amount, _desc, _cleanup) \ do { \ size_t amount = _amount; /* evaluate _amount only once */ \ if (amount > 0) { \ nsresult rv; \ rv = aHandleReport->Callback(NS_LITERAL_CSTRING("System"), _path, \ KIND_NONHEAP, _units, amount, _desc, \ aData); \ if (NS_WARN_IF(NS_FAILED(rv))) { \ _cleanup; \ return rv; \ } \ } \ } while (0) #define REPORT(_path, _amount, _desc) \ REPORT_WITH_CLEANUP(_path, UNITS_BYTES, _amount, _desc, (void)0) NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData) { if (!Preferences::GetBool("memory.system_memory_reporter")) { return NS_OK; } // Read relevant fields from /proc/meminfo. int64_t memTotal = 0, memFree = 0; nsresult rv = ReadMemInfo(&memTotal, &memFree); // Collect per-process reports from /proc/<pid>/smaps. int64_t totalPss = 0; rv = CollectProcessReports(aHandleReport, aData, &totalPss); NS_ENSURE_SUCCESS(rv, rv); // Report the non-process numbers. int64_t other = memTotal - memFree - totalPss; REPORT(NS_LITERAL_CSTRING("mem/other"), other, NS_LITERAL_CSTRING( "Memory which is neither owned by any user-space process nor free. Note that " "this includes memory holding cached files from the disk which can be " "reclaimed by the OS at any time.")); REPORT(NS_LITERAL_CSTRING("mem/free"), memFree, NS_LITERAL_CSTRING( "Memory which is free and not being used for any purpose.")); // Report reserved memory not included in memTotal. rv = CollectPmemReports(aHandleReport, aData); NS_ENSURE_SUCCESS(rv, rv); // Report zram usage statistics. rv = CollectZramReports(aHandleReport, aData); NS_ENSURE_SUCCESS(rv, rv); return rv; }
bool SysMemInfo::ReadMemInfo(const std::vector<std::string>& tags, std::vector<uint64_t>* out, const std::string& path) { out->clear(); out->resize(tags.size()); return ReadMemInfo(tags, path, [&]([[maybe_unused]] const std::string& tag, uint64_t val) { auto it = std::find(tags.begin(), tags.end(), tag); if (it == tags.end()) { LOG(ERROR) << "Tried to store invalid tag: " << tag; return; } auto index = std::distance(tags.begin(), it); // store the values in the same order as the tags out->at(index) = val; }); }
bool SysMemInfo::ReadMemInfo(std::vector<uint64_t>* out, const std::string& path) { return ReadMemInfo(SysMemInfo::kDefaultSysMemInfoTags, out, path); }
bool SysMemInfo::ReadMemInfo(const std::string& path) { return ReadMemInfo(SysMemInfo::kDefaultSysMemInfoTags, path, [&](const std::string& tag, uint64_t val) { mem_in_kb_[tag] = val; }); }