diff --git a/src/hud_elements.cpp b/src/hud_elements.cpp index 590455425c..1bca65735c 100644 --- a/src/hud_elements.cpp +++ b/src/hud_elements.cpp @@ -496,7 +496,7 @@ void HudElements::io_stats(){ void HudElements::vram(){ if (!gpus) gpus = std::make_unique(HUDElements.params); - + if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_vram]){ size_t i = 0; if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_stats]){ @@ -562,7 +562,7 @@ void HudElements::ram(){ ImguiNextColumnOrNewRow(); right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", memused); if (!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_hud_compact]){ - ImGui::SameLine(0,1.0f); + ImGui::SameLine(0, 1.0f); ImGui::PushFont(HUDElements.sw_stats->font1); HUDElements.TextColored(HUDElements.colors.text, "GiB"); ImGui::PopFont(); @@ -572,7 +572,7 @@ void HudElements::ram(){ if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_ram] && HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_swap]){ ImguiNextColumnOrNewRow(); right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", swapused); - ImGui::SameLine(0,1.0f); + ImGui::SameLine(0, 1.0f); ImGui::PushFont(HUDElements.sw_stats->font1); HUDElements.TextColored(HUDElements.colors.text, "GiB"); ImGui::PopFont(); @@ -584,33 +584,34 @@ void HudElements::procmem() { #ifdef __linux__ const char* unit = nullptr; + if (!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_procmem]) return; ImguiNextColumnFirstItem(); HUDElements.TextColored(HUDElements.colors.ram, "PMEM"); ImguiNextColumnOrNewRow(); - right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", format_units(proc_mem.resident, unit)); - ImGui::SameLine(0,1.0f); + right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", format_units(proc_mem_resident, unit)); + ImGui::SameLine(0, 1.0f); ImGui::PushFont(HUDElements.sw_stats->font1); HUDElements.TextColored(HUDElements.colors.text, "%s", unit); ImGui::PopFont(); - if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_procmem_shared]){ + if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_procmem_shared]) { ImguiNextColumnOrNewRow(); - right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", format_units(proc_mem.shared, unit)); + right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", format_units(proc_mem_shared, unit)); ImGui::SameLine(0,1.0f); ImGui::PushFont(HUDElements.sw_stats->font1); HUDElements.TextColored(HUDElements.colors.text, "%s", unit); ImGui::PopFont(); } - if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_procmem_virt]){ + if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_procmem_virt]) { ImguiNextColumnOrNewRow(); - right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", format_units(proc_mem.virt, unit)); - ImGui::SameLine(0,1.0f); + right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", format_units(proc_mem_virt, unit)); + ImGui::SameLine(0, 1.0f); ImGui::PushFont(HUDElements.sw_stats->font1); - HUDElements.TextColored(HUDElements.colors.text, "%s", unit); + HUDElements.TextColored(HUDElements.colors.text, "%s", unit); ImGui::PopFont(); } #endif @@ -839,7 +840,7 @@ void HudElements::frame_timing(){ ImPlot::SetupAxesLimits(0, 200, min_time, max_time); ImPlot::SetNextLineStyle(HUDElements.colors.frametime, 1.5); ImPlot::PlotLine("frametime line", frametime_data.data(), frametime_data.size()); - if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_throttling_status_graph] && + if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_throttling_status_graph] && gpus->active_gpu() && gpus->active_gpu()->throttling()){ ImPlot::SetNextLineStyle(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), 1.5); ImPlot::PlotLine("power line", gpus->active_gpu()->throttling()->power.data(), gpus->active_gpu()->throttling()->power.size()); diff --git a/src/memory.cpp b/src/memory.cpp index c360e97606..b19700b938 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -1,131 +1,65 @@ #include -#include "memory.h" -#include -#include -#include -#include -#include +#include +#include +#include #include +#include -struct memory_information mem_info; -float memused, memmax, swapused, swapmax; -struct process_mem proc_mem {}; +#include "memory.h" -FILE *open_file(const char *file, int *reported) { - FILE *fp = nullptr; +float memused, memmax, swapused; +uint64_t proc_mem_resident, proc_mem_shared, proc_mem_virt; - fp = fopen(file, "re"); +void update_meminfo() { + std::ifstream file("/proc/meminfo"); + std::map meminfo; - if (fp == nullptr) { - if ((reported == nullptr) || *reported == 0) { - SPDLOG_ERROR("can't open {}: {}", file, strerror(errno)); - if (reported != nullptr) { *reported = 1; } + if (!file.is_open()) { + SPDLOG_ERROR("can't open /proc/meminfo"); + return; } - return nullptr; - } - - return fp; -} - -void update_meminfo(void) { - FILE *meminfo_fp; - static int reported = 0; - /* unsigned int a; */ - char buf[256]; - - /* With multi-threading, calculations that require - * multple steps to reach a final result can cause havok - * if the intermediary calculations are directly assigned to the - * information struct (they may be read by other functions in the meantime). - * These variables keep the calculations local to the function and finish off - * the function by assigning the results to the information struct */ - unsigned long long shmem = 0, sreclaimable = 0, curmem = 0, curbufmem = 0, - cureasyfree = 0, memavail = 0; - - mem_info.memmax = mem_info.memdirty = mem_info.swap = mem_info.swapfree = mem_info.swapmax = - mem_info.memwithbuffers = mem_info.buffers = mem_info.cached = mem_info.memfree = - mem_info.memeasyfree = 0; - - if (!(meminfo_fp = open_file("/proc/meminfo", &reported))) { } - - while (!feof(meminfo_fp)) { - if (fgets(buf, 255, meminfo_fp) == nullptr) { break; } - - if (strncmp(buf, "MemTotal:", 9) == 0) { - sscanf(buf, "%*s %llu", &mem_info.memmax); - } else if (strncmp(buf, "MemFree:", 8) == 0) { - sscanf(buf, "%*s %llu", &mem_info.memfree); - } else if (strncmp(buf, "SwapTotal:", 10) == 0) { - sscanf(buf, "%*s %llu", &mem_info.swapmax); - } else if (strncmp(buf, "SwapFree:", 9) == 0) { - sscanf(buf, "%*s %llu", &mem_info.swapfree); - } else if (strncmp(buf, "Buffers:", 8) == 0) { - sscanf(buf, "%*s %llu", &mem_info.buffers); - } else if (strncmp(buf, "Cached:", 7) == 0) { - sscanf(buf, "%*s %llu", &mem_info.cached); - } else if (strncmp(buf, "Dirty:", 6) == 0) { - sscanf(buf, "%*s %llu", &mem_info.memdirty); - } else if (strncmp(buf, "MemAvailable:", 13) == 0) { - sscanf(buf, "%*s %llu", &memavail); - } else if (strncmp(buf, "Shmem:", 6) == 0) { - sscanf(buf, "%*s %llu", &shmem); - } else if (strncmp(buf, "SReclaimable:", 13) == 0) { - sscanf(buf, "%*s %llu", &sreclaimable); + for (std::string line; std::getline(file, line);) { + auto key = line.substr(0, line.find(":")); + auto val = line.substr(key.length() + 2); + meminfo[key] = std::stoull(val) / 1024.f / 1024.f; } - } - - curmem = mem_info.memwithbuffers = mem_info.memmax - mem_info.memfree; - cureasyfree = mem_info.memfree; - mem_info.swap = mem_info.swapmax - mem_info.swapfree; - /* Reclaimable memory: does not include shared memory, which is part of cached - but unreclaimable. Includes the reclaimable part of the Slab cache though. - Note: when shared memory is swapped out, shmem decreases and swapfree - decreases - we want this. - */ - curbufmem = (mem_info.cached - shmem) + mem_info.buffers + sreclaimable; + memmax = meminfo["MemTotal"]; + memused = meminfo["MemTotal"] - meminfo["MemAvailable"]; + swapused = meminfo["SwapTotal"] - meminfo["SwapFree"]; +} - curmem = mem_info.memmax - memavail; - cureasyfree += curbufmem; +void update_procmem() +{ + auto page_size = sysconf(_SC_PAGESIZE); + if (page_size < 0) page_size = 4096; - /* Now that we know that every calculation is finished we can wrap up - * by assigning the values to the information structure */ - mem_info.mem = curmem; - mem_info.bufmem = curbufmem; - mem_info.memeasyfree = cureasyfree; + std::ifstream file("/proc/self/statm"); - memused = (float(mem_info.memmax) - float(mem_info.memeasyfree)) / (1024 * 1024); - memmax = float(mem_info.memmax) / (1024 * 1024); + if (!file.is_open()) { + SPDLOG_ERROR("can't open /proc/self/statm"); + return; + } - swapused = (float(mem_info.swapmax) - float(mem_info.swapfree)) / (1024 * 1024); - swapmax = float(mem_info.swapmax) / (1024 * 1024); + size_t last_idx = 0; + std::string line; + std::getline(file, line); - fclose(meminfo_fp); -} - -void update_procmem() -{ - static int reported = 0; - FILE *statm = open_file("/proc/self/statm", &reported); - if (!statm) + if (line.empty()) return; - static auto pageSize = sysconf(_SC_PAGESIZE); - if (pageSize < 0) pageSize = 4096; + std::array meminfo; - long long int temp[7]; - if (fscanf(statm, "%lld %lld %lld %lld %lld %lld %lld", - &temp[0], &temp[1], &temp[2], &temp[3], - &temp[4], /* unused since Linux 2.6; always 0 */ - &temp[5], &temp[6]) == 7) - { - proc_mem.virt = temp[0] * pageSize;// / (1024.f * 1024.f); //MiB - proc_mem.resident = temp[1] * pageSize;// / (1024.f * 1024.f); //MiB - proc_mem.shared = temp[2] * pageSize;// / (1024.f * 1024.f); //MiB; - proc_mem.text = temp[3]; - proc_mem.data = temp[5]; - proc_mem.dirty = temp[6]; + for (auto i = 0; i < 3; i++) { + auto idx = line.find(" ", last_idx); + auto val = line.substr(last_idx, idx); + + meminfo[i] = std::stoull(val) * page_size; + last_idx = idx + 1; } - fclose(statm); + + proc_mem_virt = meminfo[0]; + proc_mem_resident = meminfo[1]; + proc_mem_shared = meminfo[2]; } diff --git a/src/memory.h b/src/memory.h index 79dd0d3a01..e4b7569c77 100644 --- a/src/memory.h +++ b/src/memory.h @@ -2,28 +2,12 @@ #ifndef MANGOHUD_MEMORY_H #define MANGOHUD_MEMORY_H -#include -#include +#include -extern float memused, memmax, swapused, swapmax, rss; +extern float memused, memmax, swapused; +extern uint64_t proc_mem_resident, proc_mem_shared, proc_mem_virt; -struct memory_information { - /* memory information in kilobytes */ - unsigned long long mem, memwithbuffers, memeasyfree, memfree, memmax, - memdirty; - unsigned long long swap, swapfree, swapmax; - unsigned long long bufmem, buffers, cached; -}; - -struct process_mem -{ - int64_t virt, resident, shared; - int64_t text, data, dirty; -}; -extern process_mem proc_mem; - -void update_meminfo(void); +void update_meminfo(); void update_procmem(); -FILE *open_file(const char *file, int *reported); #endif //MANGOHUD_MEMORY_H diff --git a/src/overlay.cpp b/src/overlay.cpp index 0ff262fbab..c9aa4f802a 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -158,7 +158,7 @@ void update_hw_info(const struct overlay_params& params, uint32_t vendorID) #ifdef __linux__ currentLogData.ram_used = memused; currentLogData.swap_used = swapused; - currentLogData.process_rss = proc_mem.resident / float((2 << 29)); // GiB, consistent w/ other mem stats + currentLogData.process_rss = proc_mem_resident / float((2 << 29)); // GiB, consistent w/ other mem stats #endif currentLogData.cpu_load = cpuStats.GetCPUDataTotal().percent;