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.
This commit is contained in:
李通洲
2022-10-18 23:46:42 +08:00
parent 7bbd2aee94
commit 581c6f547d
15 changed files with 163 additions and 119 deletions
+5
View File
@@ -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()
+4 -18
View File
@@ -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);
);
}
+2 -16
View File
@@ -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
+1 -21
View File
@@ -4,7 +4,7 @@
#include <string.h>
#include <mach/mach.h>
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);
}
+1 -11
View File
@@ -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);
}
+13 -21
View File
@@ -3,13 +3,12 @@
#include <stdlib.h>
#include <string.h>
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;
}
+2 -26
View File
@@ -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);
}
+16
View File
@@ -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
+13
View File
@@ -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);
);
}
+10
View File
@@ -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
+18
View File
@@ -0,0 +1,18 @@
#include "swap.h"
#include "common/sysctl.h"
#include <mach/mach.h>
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;
}
+6
View File
@@ -0,0 +1,6 @@
#include "swap.h"
void ffDetectSwapImpl(FFMemoryStorage* swap)
{
ffStrbufAppendS(&swap->error, "Not implemented");
}
+34
View File
@@ -0,0 +1,34 @@
#include "swap.h"
#include <stdlib.h>
#include <string.h>
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;
}
+23
View File
@@ -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");
}
+15 -6
View File
@@ -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());
}