Skip to content

Commit

Permalink
refactor memory.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
17314642 committed Dec 29, 2024
1 parent c515999 commit 5f0d9f2
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 144 deletions.
25 changes: 13 additions & 12 deletions src/hud_elements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ void HudElements::io_stats(){
void HudElements::vram(){
if (!gpus)
gpus = std::make_unique<GPUS>(HUDElements.params);

if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_vram]){
size_t i = 0;
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_stats]){
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand All @@ -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
Expand Down Expand Up @@ -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());
Expand Down
156 changes: 45 additions & 111 deletions src/memory.cpp
Original file line number Diff line number Diff line change
@@ -1,131 +1,65 @@
#include <spdlog/spdlog.h>
#include "memory.h"
#include <iomanip>
#include <cstring>
#include <stdio.h>
#include <iostream>
#include <thread>
#include <map>
#include <fstream>
#include <string>
#include <unistd.h>
#include <array>

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<std::string, float> 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<uint64_t, 3> 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];
}
24 changes: 4 additions & 20 deletions src/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,12 @@
#ifndef MANGOHUD_MEMORY_H
#define MANGOHUD_MEMORY_H

#include <stdio.h>
#include <thread>
#include <cstdint>

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
2 changes: 1 addition & 1 deletion src/overlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 5f0d9f2

Please sign in to comment.