From 581c6f547dd839b812c1cbe75882b3f7ae49a284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 18 Oct 2022 23:46:42 +0800 Subject: [PATCH] Swap: split code out from memory detection 1. Since swap module is disabled by default, swap detection is unnecessary in most cases. 2. On platform other than Linux, swap detection doesn't share code with memory. 3. Swap detection can be expensive. On Windows, it requires another WMI query which can lag heavily in some cases. Don't pay for you don't use. --- CMakeLists.txt | 5 ++++ src/detection/memory/memory.c | 22 +++------------- src/detection/memory/memory.h | 18 ++----------- src/detection/memory/memory_apple.c | 22 +--------------- src/detection/memory/memory_bsd.c | 12 +-------- src/detection/memory/memory_linux.c | 34 ++++++++++--------------- src/detection/memory/memory_windows.cpp | 28 ++------------------ src/detection/storage.h | 16 ++++++++++++ src/detection/swap/swap.c | 13 ++++++++++ src/detection/swap/swap.h | 10 ++++++++ src/detection/swap/swap_apple.c | 18 +++++++++++++ src/detection/swap/swap_bsd.c | 6 +++++ src/detection/swap/swap_linux.c | 34 +++++++++++++++++++++++++ src/detection/swap/swap_windows.cpp | 23 +++++++++++++++++ src/modules/memory.c | 21 ++++++++++----- 15 files changed, 163 insertions(+), 119 deletions(-) create mode 100644 src/detection/storage.h create mode 100644 src/detection/swap/swap.c create mode 100644 src/detection/swap/swap.h create mode 100644 src/detection/swap/swap_apple.c create mode 100644 src/detection/swap/swap_bsd.c create mode 100644 src/detection/swap/swap_linux.c create mode 100644 src/detection/swap/swap_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f66eb6f62..78bbf0d33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -235,6 +235,7 @@ set(LIBFASTFETCH_SRC src/detection/cpuUsage/cpuUsage.c src/detection/gpu/gpu.c src/detection/memory/memory.c + src/detection/swap/swap.c src/detection/font/font.c src/detection/displayserver/displayserver.c src/detection/terminalfont/terminalfont.c @@ -307,6 +308,7 @@ if(LINUX OR ANDROID) list(APPEND LIBFASTFETCH_SRC src/detection/cpu/cpu_linux.c src/detection/memory/memory_linux.c + src/detection/swap/swap_linux.c ) endif() @@ -365,6 +367,7 @@ if(WIN32) src/detection/cpuUsage/cpuUsage_windows.c src/detection/cpuUsage/cpuUsage_nowait_windows.cpp src/detection/memory/memory_windows.cpp + src/detection/swap/swap_windows.cpp src/detection/font/font_windows.cpp src/detection/terminalfont/terminalfont_windows.c src/detection/localip/localip_windows.c @@ -393,6 +396,7 @@ if(APPLE) src/detection/battery/battery_apple.c src/detection/poweradapter/poweradapter_apple.c src/detection/memory/memory_apple.c + src/detection/swap/swap_apple.c src/detection/displayserver/displayserver_apple.c src/detection/terminalfont/terminalfont_apple.m src/detection/media/media_apple.m @@ -414,6 +418,7 @@ if(BSD) list(APPEND LIBFASTFETCH_SRC src/detection/cpu/cpu_bsd.c src/detection/memory/memory_bsd.c + src/detection/swap/swap_bsd.c ) endif() diff --git a/src/detection/memory/memory.c b/src/detection/memory/memory.c index 62be6197e..107e7d716 100644 --- a/src/detection/memory/memory.c +++ b/src/detection/memory/memory.c @@ -1,27 +1,13 @@ #include "memory.h" #include "detection/internal.h" -void ffDetectMemoryImpl(FFMemoryResult* memory); +void ffDetectMemoryImpl(FFMemoryStorage* memory); -static void calculatePercentage(FFMemoryStorage* storage) +const FFMemoryStorage* ffDetectMemory() { - if(storage->error.length != 0) - return; - - if(storage->bytesTotal == 0) - storage->percentage = 0; - else - storage->percentage = (uint8_t) (((long double) storage->bytesUsed / (long double) storage->bytesTotal) * 100.0); -} - -const FFMemoryResult* ffDetectMemory() -{ - FF_DETECTION_INTERNAL_GUARD(FFMemoryResult, - ffStrbufInitA(&result.ram.error, 0); - ffStrbufInitA(&result.swap.error, 0); + FF_DETECTION_INTERNAL_GUARD(FFMemoryStorage, + ffStrbufInit(&result.error); ffDetectMemoryImpl(&result); - calculatePercentage(&result.ram); - calculatePercentage(&result.swap); ); } diff --git a/src/detection/memory/memory.h b/src/detection/memory/memory.h index a46d259c1..1114ff4cb 100644 --- a/src/detection/memory/memory.h +++ b/src/detection/memory/memory.h @@ -3,22 +3,8 @@ #ifndef FF_INCLUDED_detection_memory_memory #define FF_INCLUDED_detection_memory_memory -#include "fastfetch.h" +#include "detection/storage.h" -typedef struct FFMemoryStorage -{ - FFstrbuf error; - uint64_t bytesUsed; - uint64_t bytesTotal; - uint8_t percentage; -} FFMemoryStorage; - -typedef struct FFMemoryResult -{ - FFMemoryStorage ram; - FFMemoryStorage swap; -} FFMemoryResult; - -const FFMemoryResult* ffDetectMemory(); +const FFMemoryStorage* ffDetectMemory(); #endif diff --git a/src/detection/memory/memory_apple.c b/src/detection/memory/memory_apple.c index 235b13443..b3616ec59 100644 --- a/src/detection/memory/memory_apple.c +++ b/src/detection/memory/memory_apple.c @@ -4,7 +4,7 @@ #include #include -static void detectRam(FFMemoryStorage* ram) +void ffDetectMemoryImpl(FFMemoryStorage* ram) { ram->bytesTotal = (uint64_t) ffSysctlGetInt64("hw.memsize", 0); if(ram->bytesTotal == 0) @@ -30,23 +30,3 @@ static void detectRam(FFMemoryStorage* ram) ram->bytesUsed = ((uint64_t) vmstat.active_count + vmstat.wire_count) * pagesize; } - -static void detectSwap(FFMemoryStorage* swap) -{ - struct xsw_usage xsw; - size_t size = sizeof(xsw); - if(sysctlbyname("vm.swapusage", &xsw, &size, 0, 0) != 0) - { - ffStrbufAppendS(&swap->error, "Failed to read vm.swapusage"); - return; - } - - swap->bytesTotal = xsw.xsu_total; - swap->bytesUsed = xsw.xsu_used; -} - -void ffDetectMemoryImpl(FFMemoryResult* memory) -{ - detectRam(&memory->ram); - detectSwap(&memory->swap); -} diff --git a/src/detection/memory/memory_bsd.c b/src/detection/memory/memory_bsd.c index 55f34c83c..881b3dfb3 100644 --- a/src/detection/memory/memory_bsd.c +++ b/src/detection/memory/memory_bsd.c @@ -1,7 +1,7 @@ #include "memory.h" #include "common/sysctl.h" -static void detectRam(FFMemoryStorage* ram) +void ffDetectMemoryImpl(FFMemoryStorage* ram) { uint32_t pageSize = (uint32_t) ffSysctlGetInt("hw.pagesize", 0); if(pageSize == 0) @@ -22,13 +22,3 @@ static void detectRam(FFMemoryStorage* ram) - (uint64_t) ffSysctlGetInt64("vm.stats.vm.v_inactive_count", 0) * pageSize ; } - -static void detectSwap(FFMemoryStorage* swap) -{ - ffStrbufAppendS(&swap->error, "Not implemented"); -} -void ffDetectMemoryImpl(FFMemoryResult* memory) -{ - detectRam(&memory->ram); - detectSwap(&memory->swap); -} diff --git a/src/detection/memory/memory_linux.c b/src/detection/memory/memory_linux.c index b83819295..3a5d55ee0 100644 --- a/src/detection/memory/memory_linux.c +++ b/src/detection/memory/memory_linux.c @@ -3,13 +3,12 @@ #include #include -void ffDetectMemoryImpl(FFMemoryResult* memory) +void ffDetectMemoryImpl(FFMemoryStorage* swap) { FILE* meminfo = fopen("/proc/meminfo", "r"); if(meminfo == NULL) { - ffStrbufAppendS(&memory->ram.error, "Failed to open /proc/meminfo"); - ffStrbufAppendS(&memory->swap.error, "Failed to open /proc/meminfo"); + ffStrbufAppendS(&swap->error, "Failed to open /proc/meminfo"); return; } @@ -21,20 +20,16 @@ void ffDetectMemoryImpl(FFMemoryResult* memory) memFree = 0, buffers = 0, cached = 0, - sReclaimable = 0, - swapTotal = 0, - swapFree = 0; + sReclaimable = 0; while (getline(&line, &len, meminfo) != EOF) { - sscanf(line, "MemTotal: %u", &memTotal); - sscanf(line, "Shmem: %u", &shmem); - sscanf(line, "MemFree: %u", &memFree); - sscanf(line, "Buffers: %u", &buffers); - sscanf(line, "Cached: %u", &cached); - sscanf(line, "SReclaimable: %u", &sReclaimable); - sscanf(line, "SwapTotal: %u", &swapTotal); - sscanf(line, "SwapFree: %u", &swapFree); + if(!sscanf(line, "MemTotal: %u", &memTotal)) + if(!sscanf(line, "Shmem: %u", &shmem)) + if(!sscanf(line, "MemFree: %u", &memFree)) + if(!sscanf(line, "Buffers: %u", &buffers)) + if(!sscanf(line, "Cached: %u", &cached)) + sscanf(line, "SReclaimable: %u", &sReclaimable); } if(line != NULL) @@ -42,12 +37,9 @@ void ffDetectMemoryImpl(FFMemoryResult* memory) fclose(meminfo); - memory->ram.bytesTotal = memTotal * (uint64_t) 1024; - if(memory->ram.bytesTotal == 0) - ffStrbufAppendS(&memory->ram.error, "Failed to read MemTotal"); + swap->bytesTotal = memTotal * (uint64_t) 1024; + if(swap->bytesTotal == 0) + ffStrbufAppendS(&swap->error, "Failed to read MemTotal"); else - memory->ram.bytesUsed = (memTotal + shmem - memFree - buffers - cached - sReclaimable) * (uint64_t) 1024; - - memory->swap.bytesTotal = swapTotal * (uint64_t) 1024; - memory->swap.bytesUsed = (swapTotal - swapFree) * (uint64_t) 1024; + swap->bytesUsed = (memTotal + shmem - memFree - buffers - cached - sReclaimable) * (uint64_t) 1024; } diff --git a/src/detection/memory/memory_windows.cpp b/src/detection/memory/memory_windows.cpp index a11308e0d..122e28d26 100644 --- a/src/detection/memory/memory_windows.cpp +++ b/src/detection/memory/memory_windows.cpp @@ -3,7 +3,8 @@ extern "C" { } #include "util/windows/wmi.hpp" -void detectRam(FFMemoryStorage* ram) +extern "C" +void ffDetectMemoryImpl(FFMemoryStorage* ram) { FFWmiQuery query(L"SELECT TotalVisibleMemorySize, FreePhysicalMemory FROM Win32_OperatingSystem", &ram->error); if(!query) @@ -22,28 +23,3 @@ void detectRam(FFMemoryStorage* ram) else ffStrbufInitS(&ram->error, "No Wmi result returned"); } - -void detectSwap(FFMemoryStorage* swap) -{ - FFWmiQuery query(L"SELECT AllocatedBaseSize, CurrentUsage FROM Win32_PageFileUsage", &swap->error); - if(!query) - return; - - if(FFWmiRecord record = query.next()) - { - //MB - record.getUnsigned(L"AllocatedBaseSize", &swap->bytesTotal); - record.getUnsigned(L"CurrentUsage", &swap->bytesUsed); - swap->bytesTotal *= 1024 * 1024; - swap->bytesUsed *= 1024 * 1024; - } - else - ffStrbufInitS(&swap->error, "No Wmi result returned"); -} - -extern "C" -void ffDetectMemoryImpl(FFMemoryResult* memory) -{ - detectRam(&memory->ram); - detectSwap(&memory->swap); -} diff --git a/src/detection/storage.h b/src/detection/storage.h new file mode 100644 index 000000000..c4cce7ede --- /dev/null +++ b/src/detection/storage.h @@ -0,0 +1,16 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_storage +#define FF_INCLUDED_detection_storage + +#include "fastfetch.h" + +typedef struct FFMemoryStorage +{ + FFstrbuf error; + uint64_t bytesUsed; + uint64_t bytesTotal; + uint8_t percentage; +} FFMemoryStorage; + +#endif diff --git a/src/detection/swap/swap.c b/src/detection/swap/swap.c new file mode 100644 index 000000000..0a790c9f7 --- /dev/null +++ b/src/detection/swap/swap.c @@ -0,0 +1,13 @@ +#include "swap.h" +#include "detection/internal.h" + +void ffDetectSwapImpl(FFMemoryStorage* swap); + +const FFMemoryStorage* ffDetectSwap() +{ + FF_DETECTION_INTERNAL_GUARD(FFMemoryStorage, + ffStrbufInit(&result.error); + + ffDetectSwapImpl(&result); + ); +} diff --git a/src/detection/swap/swap.h b/src/detection/swap/swap.h new file mode 100644 index 000000000..a0374cf2b --- /dev/null +++ b/src/detection/swap/swap.h @@ -0,0 +1,10 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_swap_swap +#define FF_INCLUDED_detection_swap_swap + +#include "detection/storage.h" + +const FFMemoryStorage* ffDetectSwap(); + +#endif diff --git a/src/detection/swap/swap_apple.c b/src/detection/swap/swap_apple.c new file mode 100644 index 000000000..19ea32c00 --- /dev/null +++ b/src/detection/swap/swap_apple.c @@ -0,0 +1,18 @@ +#include "swap.h" +#include "common/sysctl.h" + +#include + +void ffDetectSwapImpl(FFMemoryStorage* swap) +{ + struct xsw_usage xsw; + size_t size = sizeof(xsw); + if(sysctlbyname("vm.swapusage", &xsw, &size, 0, 0) != 0) + { + ffStrbufAppendS(&swap->error, "Failed to read vm.swapusage"); + return; + } + + swap->bytesTotal = xsw.xsu_total; + swap->bytesUsed = xsw.xsu_used; +} diff --git a/src/detection/swap/swap_bsd.c b/src/detection/swap/swap_bsd.c new file mode 100644 index 000000000..8af98a16f --- /dev/null +++ b/src/detection/swap/swap_bsd.c @@ -0,0 +1,6 @@ +#include "swap.h" + +void ffDetectSwapImpl(FFMemoryStorage* swap) +{ + ffStrbufAppendS(&swap->error, "Not implemented"); +} diff --git a/src/detection/swap/swap_linux.c b/src/detection/swap/swap_linux.c new file mode 100644 index 000000000..e176bb158 --- /dev/null +++ b/src/detection/swap/swap_linux.c @@ -0,0 +1,34 @@ +#include "swap.h" + +#include +#include + +void ffDetectSwapImpl(FFMemoryStorage* swap) +{ + FILE* meminfo = fopen("/proc/meminfo", "r"); + if(meminfo == NULL) + { + ffStrbufAppendS(&swap->error, "Failed to open /proc/meminfo"); + return; + } + + char* line = NULL; + size_t len = 0; + + uint32_t swapTotal = 0, + swapFree = 0; + + while (getline(&line, &len, meminfo) != EOF) + { + if(!sscanf(line, "SwapTotal: %u", &swapTotal)) + sscanf(line, "SwapFree: %u", &swapFree); + } + + if(line != NULL) + free(line); + + fclose(meminfo); + + swap->bytesTotal = swapTotal * (uint64_t) 1024; + swap->bytesUsed = (swapTotal - swapFree) * (uint64_t) 1024; +} diff --git a/src/detection/swap/swap_windows.cpp b/src/detection/swap/swap_windows.cpp new file mode 100644 index 000000000..6e82cccab --- /dev/null +++ b/src/detection/swap/swap_windows.cpp @@ -0,0 +1,23 @@ +extern "C" { +#include "swap.h" +} +#include "util/windows/wmi.hpp" + +extern "C" +void ffDetectSwapImpl(FFMemoryStorage* swap) +{ + FFWmiQuery query(L"SELECT AllocatedBaseSize, CurrentUsage FROM Win32_PageFileUsage", &swap->error); + if(!query) + return; + + if(FFWmiRecord record = query.next()) + { + //MB + record.getUnsigned(L"AllocatedBaseSize", &swap->bytesTotal); + record.getUnsigned(L"CurrentUsage", &swap->bytesUsed); + swap->bytesTotal *= 1024 * 1024; + swap->bytesUsed *= 1024 * 1024; + } + else + ffStrbufInitS(&swap->error, "No Wmi result returned"); +} diff --git a/src/modules/memory.c b/src/modules/memory.c index f3f2c17ee..c3681a136 100644 --- a/src/modules/memory.c +++ b/src/modules/memory.c @@ -2,12 +2,21 @@ #include "common/printing.h" #include "common/parsing.h" #include "detection/memory/memory.h" +#include "detection/swap/swap.h" #define FF_MEMORY_MODULE_NAME "Memory" #define FF_SWAP_MODULE_NAME "Swap" #define FF_MEMORY_NUM_FORMAT_ARGS 3 +static uint8_t calculatePercentage(const FFMemoryStorage* storage) +{ + if(storage->error.length != 0 || storage->bytesTotal == 0) + return 0; + else + return (uint8_t) (((long double) storage->bytesUsed / (long double) storage->bytesTotal) * 100.0); +} + static void printMemory(FFinstance* instance, const char* name, const FFModuleArgs* moduleArgs, const FFMemoryStorage* storage) { if(storage->error.length > 0) @@ -24,20 +33,22 @@ static void printMemory(FFinstance* instance, const char* name, const FFModuleAr ffStrbufInit(&totalPretty); ffParseSize(storage->bytesTotal, instance->config.binaryPrefixType, &totalPretty); + uint8_t percentage = calculatePercentage(storage); + if(moduleArgs->outputFormat.length == 0) { ffPrintLogoAndKey(instance, name, 0, &moduleArgs->key); if (storage->bytesTotal == 0) puts("Disabled"); else - printf("%s / %s (%u%%)\n", usedPretty.chars, totalPretty.chars, storage->percentage); + printf("%s / %s (%u%%)\n", usedPretty.chars, totalPretty.chars, percentage); } else { ffPrintFormat(instance, name, 0, moduleArgs, FF_MEMORY_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty}, {FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty}, - {FF_FORMAT_ARG_TYPE_UINT8, &storage->percentage}, + {FF_FORMAT_ARG_TYPE_UINT8, &percentage}, }); } @@ -47,12 +58,10 @@ static void printMemory(FFinstance* instance, const char* name, const FFModuleAr void ffPrintMemory(FFinstance* instance) { - const FFMemoryResult* memory = ffDetectMemory(); - printMemory(instance, FF_MEMORY_MODULE_NAME, &instance->config.memory, &memory->ram); + printMemory(instance, FF_MEMORY_MODULE_NAME, &instance->config.memory, ffDetectMemory()); } void ffPrintSwap(FFinstance* instance) { - const FFMemoryResult* memory = ffDetectMemory(); - printMemory(instance, FF_SWAP_MODULE_NAME, &instance->config.swap, &memory->swap); + printMemory(instance, FF_SWAP_MODULE_NAME, &instance->config.swap, ffDetectSwap()); }