Compare commits

..

20 Commits

Author SHA1 Message Date
李通洲 0e90f3a7d4 GPU (Windows): fixes typo 2026-06-28 17:07:48 +08:00
Carter Li 1a663e72da Release: v2.65.2 (#2425) 2026-06-28 03:55:56 -05:00
李通洲 e0ae1ac1a2 GPU (Intel): adds comments 2026-06-28 16:26:00 +08:00
李通洲 e0d141ecf6 Memory (BSD): adds underflow protection (should not happen) 2026-06-28 16:25:08 +08:00
李通洲 29eb8bb57d Chore: fixes typos 2026-06-28 16:25:07 +08:00
李通洲 bc1f240558 Memory (Linux): uses strtoull to avoid overflow in 32-bit systems 2026-06-28 16:25:07 +08:00
李通洲 3e15a2591a Release: v2.65.2 2026-06-28 16:25:07 +08:00
李通洲 0ec9443de5 Logo (Builtin): adds Turkish
Fixes #2421
2026-06-28 16:25:07 +08:00
李通洲 4a4ca9a4a8 Memory (NetBSD): takes ZFS arc bytes into account
Used logic from FreeBSD
2026-06-28 16:25:07 +08:00
李通洲 acf76e565a Memory (FreeBSD): don't query c_min if querying size fails 2026-06-28 16:25:07 +08:00
李通洲 778aa21192 Memory (SunOS): takes ZFS arc bytes into account 2026-06-28 16:25:07 +08:00
Carter Li dfdc7284a2 Memory (Linux): takes ZFS arc bytes into account
Fixes #1995
2026-06-28 16:25:07 +08:00
Carter Li 231d7fcd4d Memory (FreeBSD): takes ZFS arc bytes into account
Fixes #2418
2026-06-28 16:25:07 +08:00
Carter Li a3184601dc GPU: detects PCIe speed only in driverSpecific mode
Fixes #2419
2026-06-28 16:25:07 +08:00
李通洲 e3dfeeb8db GPU (MT): adds PCIe speed detection support 2026-06-27 09:46:30 +08:00
Carter Li ccdcd6ab6f Codec (Linux): fixes crashing on AMD GPUs
Ref: https://github.com/fastfetch-cli/fastfetch/issues/2419#issuecomment-4812121503
2026-06-27 08:12:22 +08:00
Carter Li 64d205628e Common (Settings): adds SQLITE_OPEN_NOMUTEX fiag when opening sqlite db 2026-06-26 22:52:59 +08:00
Carter Li ff13adf1b4 Logo (Builtin): updates CachyOS 2026-06-26 00:18:08 +08:00
iinsert c38fd9ec10 Chore: adds Catnap repo link to attribution comments in examples 13-16 (#2417) 2026-06-25 23:07:49 +08:00
Carter Li 96793ec604 Packaging: updates debian stuff [ci skip] 2026-06-24 14:28:35 +08:00
24 changed files with 311 additions and 110 deletions
+19
View File
@@ -1,3 +1,22 @@
# 2.65.2
Changes:
* Memory usage calculations now exclude the ZFS ARC cache on Linux, FreeBSD, NetBSD, and SunOS. (#1995 / #2418, Memory)
* This prevents the Memory module from reporting artificially high memory usage on systems with the ZFS kmod enabled.
Bugfixes:
* The GPU module no longer pings sleeping dedicated GPUs on dual-GPU laptops. (#2419, GPU)
* As a result, PCIe link speed detection (introduced in v2.65.0) is now only enabled in `driverSpecific` mode.
* Fixed a crash when detecting hardware codec support with the `amdgpu` driver on Linux. (#2419, Codec, Linux)
Logos:
* Updated CachyOS_small
* Added Turkish
# 2.65.1
No changes
# 2.65.0
Changes:
+1 -1
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch
VERSION 2.65.1
VERSION 2.65.2
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
+6
View File
@@ -1,3 +1,9 @@
fastfetch (2.65.1~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.65.1
-- Carter Li <zhangsongcui@live.cn> Wed, 24 Jun 2026 14:21:06 +0800
fastfetch (2.64.2~#UBUNTU_CODENAME#) #UBUNTU_CODENAME#; urgency=medium
* Update to 2.64.2
+1 -1
View File
@@ -10,7 +10,7 @@ SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
ROOT_DIR="$(cd -- "$SCRIPT_DIR/.." >/dev/null 2>&1 && pwd)"
OUT_DIR="$(dirname "$ROOT_DIR")"
PPA="ppa:zhangsongcui3371/fastfetch"
CODENAMES=( jammy noble plucky questing resolute )
CODENAMES=( jammy noble plucky questing resolute stonking )
DRY_RUN=0
if [[ -d "$OUT_DIR/build" ]]; then
+1 -1
View File
@@ -1,4 +1,4 @@
// Inspired by Catnap
// Inspired by Catnap (https://github.com/iinsertNameHere/catnap)
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
+1 -1
View File
@@ -1,4 +1,4 @@
// Inspired by Catnap
// Inspired by Catnap (https://github.com/iinsertNameHere/catnap)
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
+1 -1
View File
@@ -1,4 +1,4 @@
// Inspired by Catnap
// Inspired by Catnap (https://github.com/iinsertNameHere/catnap)
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
+1 -1
View File
@@ -1,4 +1,4 @@
// Inspired by Catnap
// Inspired by Catnap (https://github.com/iinsertNameHere/catnap)
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
+1 -1
View File
@@ -391,7 +391,7 @@ int ffSettingsGetSQLite3Int(const char* dbPath, const char* query) {
}
sqlite3* db;
if (data->ffsqlite3_open_v2(dbPath, &db, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) {
if (data->ffsqlite3_open_v2(dbPath, &db, SQLITE_OPEN_READONLY | SQLITE_OPEN_NOMUTEX, NULL) != SQLITE_OK) {
return 0;
}
+1 -1
View File
@@ -237,7 +237,7 @@ static const char* detectCodecByVaDrm(FFVAData* vaData, FFCodecOptions* options,
continue;
}
FF_AUTO_CLOSE_FD int fd = openat(drifd, entry->d_name, O_RDONLY | O_CLOEXEC);
FF_AUTO_CLOSE_FD int fd = openat(drifd, entry->d_name, O_RDWR | O_CLOEXEC);
if (fd < 0) {
continue;
}
+3
View File
@@ -64,6 +64,9 @@ typedef struct FFGPUResult {
uint64_t deviceId;
} FFGPUResult;
static_assert(sizeof(((FFGPUResult*) NULL)->pcieSpeed) == 8, "pcieSpeed is not 8 bytes");
static_assert(sizeof(((FFGPUResult*) NULL)->psMax) == 4, "psMax has padding");
const char* ffDetectGPU(const FFGPUOptions* options, FFlist* result);
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus);
+5 -2
View File
@@ -66,7 +66,10 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
}
uint32_t deviceCount = 0;
if (igclData.ffctlEnumerateDevices(igclData.apiHandle, &deviceCount, NULL)) {
// ctlEnumerateDevices MUST be called with deviceCount = 0 and devices = NULL first,
// otherwise it will be silently ignored and return CTL_RESULT_SUCCESS with deviceCount and devices unmodified.
// VERY STRANGE BEHAVIOR
if (igclData.ffctlEnumerateDevices(igclData.apiHandle, &deviceCount, NULL) != CTL_RESULT_SUCCESS) {
return "ctlEnumerateDevices(NULL) failed";
}
if (deviceCount == 0) {
@@ -74,7 +77,7 @@ const char* ffDetectIntelGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverRe
}
FF_AUTO_FREE ctl_device_adapter_handle_t* devices = malloc(deviceCount * sizeof(*devices));
if (igclData.ffctlEnumerateDevices(igclData.apiHandle, &deviceCount, devices)) {
if (igclData.ffctlEnumerateDevices(igclData.apiHandle, &deviceCount, devices) != CTL_RESULT_SUCCESS) {
return "ctlEnumerateDevices(devices) failed";
}
+32 -30
View File
@@ -410,34 +410,6 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
pciDetectDriver(&gpu->driver, deviceDir, buffer, drmKey);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
ffStrbufAppendS(deviceDir, "/max_link_speed");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psMax.gen = pcieLinkSpeedToGen(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
if (gpu->psMax.gen != FF_GPU_PCIE_SPEED_UNSET) {
ffStrbufAppendS(deviceDir, "/max_link_width");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psMax.lanes = pcieWidthToLanes(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
ffStrbufAppendS(deviceDir, "/current_link_speed");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psCurr.gen = pcieLinkSpeedToGen(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
if (gpu->psCurr.gen != FF_GPU_PCIE_SPEED_UNSET) {
ffStrbufAppendS(deviceDir, "/current_link_width");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psCurr.lanes = pcieWidthToLanes(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD) {
bool ok = false;
if (drmKey && options->driverSpecific) {
@@ -473,7 +445,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
pciDetectTempGeneral(options, gpu, deviceDir, buffer);
pciDetectZxSpecific(options, gpu, deviceDir, buffer);
} else {
ffGPUDetectDriverSpecific(options, gpu, (FFGpuDriverPciBusId) {
ffGPUDetectDriverSpecific(options, gpu, (FFGpuDriverPciBusId){
.domain = pciDomain,
.bus = pciBus,
.device = pciDevice,
@@ -487,11 +459,41 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
ffGPUFillVendorByDeviceName(gpu);
if (options->driverSpecific && gpu->pcieSpeed == FF_GPU_PCIE_SPEED_UNSET) {
ffStrbufAppendS(deviceDir, "/max_link_speed");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psMax.gen = pcieLinkSpeedToGen(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
if (gpu->psMax.gen != FF_GPU_PCIE_SPEED_UNSET) {
ffStrbufAppendS(deviceDir, "/max_link_width");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psMax.lanes = pcieWidthToLanes(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
ffStrbufAppendS(deviceDir, "/current_link_speed");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psCurr.gen = pcieLinkSpeedToGen(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
if (gpu->psCurr.gen != FF_GPU_PCIE_SPEED_UNSET) {
ffStrbufAppendS(deviceDir, "/current_link_width");
if (ffReadFileBuffer(deviceDir->chars, buffer)) {
gpu->psCurr.lanes = pcieWidthToLanes(buffer);
}
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
}
}
return NULL;
}
#if __aarch64__
#include "detection/cpu/cpu.h"
#include "detection/cpu/cpu.h"
FF_A_UNUSED static const char* drmDetectAsahiSpecific(FFGPUResult* gpu, const char* name, FF_A_UNUSED FFstrbuf* buffer, FF_A_UNUSED const char* drmKey) {
if (sscanf(name, "agx-t%lu", &gpu->deviceId) == 1) {
+14
View File
@@ -190,6 +190,20 @@ const char* ffDetectMthreadsGpuInfo(const FFGpuDriverCondition* cond, FFGpuDrive
}
}
if (result.psCurr || result.psMax) {
MtmlPciInfo pciInfo;
if (mtmlData.ffmtmlDeviceGetPciInfo(device, &pciInfo) == MTML_SUCCESS) {
if (result.psCurr) {
result.psCurr->lanes = (uint16_t) pciInfo.pciCurWidth;
result.psCurr->gen = (uint16_t) pciInfo.pciCurGen;
}
if (result.psMax) {
result.psMax->lanes = (uint16_t) pciInfo.pciMaxWidth;
result.psMax->gen = (uint16_t) pciInfo.pciMaxGen;
}
}
}
return NULL;
#else
+48 -37
View File
@@ -21,7 +21,7 @@
#define GUID_DEVCLASS_DISPLAY_STRING L"{4d36e968-e325-11ce-bfc1-08002be10318}" // Found in <devguid.h>
static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds) {
static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds, bool queryPcieGen) {
FF_DEBUG("Query PCI device info: %08llX", gpu->deviceId);
static FFlist deviceIdsCache;
@@ -107,42 +107,44 @@ static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds
FF_DEBUG("Failed to get PCI bus number");
}
DEVPROPTYPE propType;
if (queryPcieGen) {
DEVPROPTYPE propType;
pciBufLen = sizeof(entry->maxLinkSpeed);
// Reports PCEe gen despite the PKEY name
CONFIGRET ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_MaxLinkSpeed, &propType, (PBYTE) &entry->maxLinkSpeed, &pciBufLen, 0);
if (ret == CR_SUCCESS) {
FF_DEBUG("PCIe max GEN: %u", entry->maxLinkSpeed);
} else {
FF_DEBUG("Failed to get PCIe max GEN: %s", ffDebugConfigRet(ret));
}
if (entry->maxLinkSpeed != FF_GPU_PCIE_SPEED_UNSET) {
pciBufLen = sizeof(entry->maxLinkWidth);
ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_MaxLinkWidth, &propType, (PBYTE) &entry->maxLinkWidth, &pciBufLen, 0);
pciBufLen = sizeof(entry->maxLinkSpeed);
// Reports PCIe gen despite the PKEY name
CONFIGRET ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_MaxLinkSpeed, &propType, (PBYTE) &entry->maxLinkSpeed, &pciBufLen, 0);
if (ret == CR_SUCCESS) {
FF_DEBUG("PCIe max link width: %u", entry->maxLinkWidth);
FF_DEBUG("PCIe max GEN: %u", entry->maxLinkSpeed);
} else {
FF_DEBUG("Failed to get PCIe max link width: %s", ffDebugConfigRet(ret));
FF_DEBUG("Failed to get PCIe max GEN: %s", ffDebugConfigRet(ret));
}
}
pciBufLen = sizeof(entry->currentLinkSpeed);
ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_CurrentLinkSpeed, &propType, (PBYTE) &entry->currentLinkSpeed, &pciBufLen, 0);
if (ret == CR_SUCCESS) {
FF_DEBUG("PCIe GEN: %u", entry->currentLinkSpeed);
} else {
FF_DEBUG("Failed to get PCIe GEN: %s", ffDebugConfigRet(ret));
}
if (entry->maxLinkSpeed != FF_GPU_PCIE_SPEED_UNSET) {
pciBufLen = sizeof(entry->maxLinkWidth);
ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_MaxLinkWidth, &propType, (PBYTE) &entry->maxLinkWidth, &pciBufLen, 0);
if (ret == CR_SUCCESS) {
FF_DEBUG("PCIe max link width: %u", entry->maxLinkWidth);
} else {
FF_DEBUG("Failed to get PCIe max link width: %s", ffDebugConfigRet(ret));
}
}
if (entry->currentLinkSpeed != FF_GPU_PCIE_SPEED_UNSET) {
pciBufLen = sizeof(entry->currentLinkWidth);
ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_CurrentLinkWidth, &propType, (PBYTE) &entry->currentLinkWidth, &pciBufLen, 0);
pciBufLen = sizeof(entry->currentLinkSpeed);
ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_CurrentLinkSpeed, &propType, (PBYTE) &entry->currentLinkSpeed, &pciBufLen, 0);
if (ret == CR_SUCCESS) {
FF_DEBUG("PCIe current link width: %u", entry->currentLinkWidth);
FF_DEBUG("PCIe GEN: %u", entry->currentLinkSpeed);
} else {
FF_DEBUG("Failed to get PCIe current link width: %s", ffDebugConfigRet(ret));
FF_DEBUG("Failed to get PCIe GEN: %s", ffDebugConfigRet(ret));
}
if (entry->currentLinkSpeed != FF_GPU_PCIE_SPEED_UNSET) {
pciBufLen = sizeof(entry->currentLinkWidth);
ret = CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_PciDevice_CurrentLinkWidth, &propType, (PBYTE) &entry->currentLinkWidth, &pciBufLen, 0);
if (ret == CR_SUCCESS) {
FF_DEBUG("PCIe current link width: %u", entry->currentLinkWidth);
} else {
FF_DEBUG("Failed to get PCIe current link width: %s", ffDebugConfigRet(ret));
}
}
}
}
@@ -151,13 +153,16 @@ static bool queryPciDeviceInfo(FFGPUResult* gpu, D3DKMT_DEVICE_IDS* outDeviceIds
FF_LIST_FOR_EACH (CacheEntry, entry, deviceIdsCache) {
if (gpu->deviceId == entry->adapterAddress) {
FF_DEBUG("Cache hit for adapter address: %08llX", gpu->deviceId);
if (outDeviceIds->VendorID != -1u) {
if (outDeviceIds->VendorID == -1u) {
*outDeviceIds = entry->deviceIds;
}
gpu->psMax.gen = (uint16_t) entry->maxLinkSpeed;
gpu->psMax.lanes = (uint16_t) entry->maxLinkWidth;
gpu->psCurr.gen = (uint16_t) entry->currentLinkSpeed;
gpu->psCurr.lanes = (uint16_t) entry->currentLinkWidth;
if (queryPcieGen) {
gpu->psMax.gen = (uint16_t) entry->maxLinkSpeed;
gpu->psMax.lanes = (uint16_t) entry->maxLinkWidth;
gpu->psCurr.gen = (uint16_t) entry->currentLinkSpeed;
gpu->psCurr.lanes = (uint16_t) entry->currentLinkWidth;
}
return true;
}
}
@@ -371,9 +376,9 @@ ffGPUDetectWsl2
FF_DEBUG("KMTQAITYPE_PHYSICALADAPTERDEVICEIDS query failed for adapter #%u: %s", i, ffDebugNtStatus(status));
}
#if _WIN32
if (adapterAddress.BusNumber != -1u) {
if (queryPciDeviceInfo(gpu, &deviceIds.DeviceIds) && gpu->vendor.length == 0) {
#if _WIN32 && FF_WIN81_COMPAT
if (adapterAddress.BusNumber != -1u && (deviceIds.DeviceIds.VendorID == -1u || options->driverSpecific)) {
if (queryPciDeviceInfo(gpu, &deviceIds.DeviceIds, options->driverSpecific) && gpu->vendor.length == 0) {
ffStrbufSetStatic(&gpu->vendor, ffGPUGetVendorString(deviceIds.DeviceIds.VendorID));
}
}
@@ -448,6 +453,12 @@ ffGPUDetectWsl2
FF_DEBUG("Attempting to query vendor name via registry for adapter #%u", i);
queryVendorNameViaRegistry(&gpu->vendor, adapter->hAdapter);
}
#if !FF_WIN81_COMPAT
if (adapterAddress.BusNumber != -1u && options->driverSpecific && gpu->pcieSpeed == FF_GPU_PCIE_SPEED_UNSET) {
queryPciDeviceInfo(gpu, &deviceIds.DeviceIds, options->driverSpecific);
}
#endif
#endif
if (gpu->name.length == 0) {
+8 -1
View File
@@ -9,8 +9,15 @@ const char* ffDetectMemory(FFMemoryResult* ram) {
// vm.stats.vm.* are int values
int32_t pagesFree = ffSysctlGetInt("vm.stats.vm.v_free_count", 0) + ffSysctlGetInt("vm.stats.vm.v_inactive_count", 0) + ffSysctlGetInt("vm.stats.vm.v_cache_count", 0);
int64_t bytesCache = ffSysctlGetInt64("vfs.bufspace", 0);
ram->bytesUsed = ram->bytesTotal - (uint64_t) pagesFree * instance.state.platform.sysinfo.pageSize;
ram->bytesUsed = ram->bytesTotal - (uint64_t) pagesFree * instance.state.platform.sysinfo.pageSize - (uint64_t) bytesCache;
int64_t bytesArc = ffSysctlGetInt64("kstat.zfs.misc.arcstats.size", 0);
if (bytesArc > 0) bytesArc -= ffSysctlGetInt64("kstat.zfs.misc.arcstats.c_min", 0);
if (bytesArc > 0 && (uint64_t) bytesArc < ram->bytesUsed) {
ram->bytesUsed -= (uint64_t) bytesArc;
}
return NULL;
}
+58 -19
View File
@@ -1,8 +1,5 @@
#include "memory.h"
#include "common/io.h"
#include "common/mallocHelper.h"
#include <inttypes.h>
const char* ffDetectMemory(FFMemoryResult* ram) {
char buf[PROC_FILE_BUFFSIZ];
@@ -21,35 +18,35 @@ const char* ffDetectMemory(FFMemoryResult* ram) {
sReclaimable = 0;
char* token = NULL;
if ((token = strstr(buf, "MemTotal:")) != NULL) {
memTotal = strtoul(token + strlen("MemTotal:"), NULL, 10);
if ((token = memmem(buf, (size_t) nRead, "MemTotal:", strlen("MemTotal:"))) != NULL) {
memTotal = (uint64_t) strtoull(token + strlen("MemTotal:"), NULL, 10);
} else {
return "MemTotal not found in /proc/meminfo";
}
if ((token = strstr(buf, "MemAvailable:")) != NULL) {
memAvailable = strtoul(token + strlen("MemAvailable:"), NULL, 10);
if ((token = memmem(buf, (size_t) nRead, "MemAvailable:", strlen("MemAvailable:"))) != NULL) {
memAvailable = (uint64_t) strtoull(token + strlen("MemAvailable:"), NULL, 10);
}
if (memAvailable == 0 || memAvailable >= memTotal) // MemAvailable can be unreasonable. #1988
{
if ((token = strstr(buf, "MemFree:")) != NULL) {
memFree = strtoul(token + strlen("MemFree:"), NULL, 10);
if (memAvailable == 0 || memAvailable >= memTotal) { // MemAvailable can be unreasonable. #1988
if ((token = memmem(buf, (size_t) nRead, "MemFree:", strlen("MemFree:"))) != NULL) {
memFree = (uint64_t) strtoull(token + strlen("MemFree:"), NULL, 10);
}
if ((token = strstr(buf, "Buffers:")) != NULL) {
buffers = strtoul(token + strlen("Buffers:"), NULL, 10);
if ((token = memmem(buf, (size_t) nRead, "Buffers:", strlen("Buffers:"))) != NULL) {
buffers = (uint64_t) strtoull(token + strlen("Buffers:"), NULL, 10);
}
if ((token = strstr(buf, "Cached:")) != NULL) {
cached = strtoul(token + strlen("Cached:"), NULL, 10);
if ((token = memmem(buf, (size_t) nRead, "Cached:", strlen("Cached:"))) != NULL) {
cached = (uint64_t) strtoull(token + strlen("Cached:"), NULL, 10);
}
if ((token = strstr(buf, "Shmem:")) != NULL) {
shmem = strtoul(token + strlen("Shmem:"), NULL, 10);
if ((token = memmem(buf, (size_t) nRead, "Shmem:", strlen("Shmem:"))) != NULL) {
shmem = (uint64_t) strtoull(token + strlen("Shmem:"), NULL, 10);
}
if ((token = strstr(buf, "SReclaimable:")) != NULL) {
sReclaimable = strtoul(token + strlen("SReclaimable:"), NULL, 10);
if ((token = memmem(buf, (size_t) nRead, "SReclaimable:", strlen("SReclaimable:"))) != NULL) {
sReclaimable = (uint64_t) strtoull(token + strlen("SReclaimable:"), NULL, 10);
}
memAvailable = memFree + buffers + cached + sReclaimable - shmem;
@@ -58,5 +55,47 @@ const char* ffDetectMemory(FFMemoryResult* ram) {
ram->bytesTotal = memTotal * 1024lu;
ram->bytesUsed = (memTotal - memAvailable) * 1024lu;
uint64_t arcSize = 0;
nRead = ffReadFileData("/proc/spl/kstat/zfs/arcstats", ARRAY_SIZE(buf) - 1, buf);
if (nRead > 0) {
buf[nRead] = '\0';
// 24 1 0x01 148 40256 2053603602 851614020716
// name type data
// hits 4 752
// Skip first line
const char* p = memchr(buf, '\n', (size_t) nRead);
if (__builtin_expect(p != NULL, true)) {
++p;
nRead -= (p - buf);
assert(nRead > 0);
// Find line offset of data
const char* pData = memmem(p, (size_t) nRead, "data\n", strlen("data\n"));
if (__builtin_expect(pData != NULL, true)) {
uint32_t dataOffset = (uint32_t) (pData - p);
p += dataOffset + strlen("data\n");
nRead -= (ssize_t) (dataOffset + strlen("data\n"));
assert(nRead > 0);
if ((token = memmem(p, (size_t) nRead, "\nsize ", strlen("\nsize "))) != NULL) {
arcSize = (uint64_t) strtoull(token + 1 + dataOffset, NULL, 10);
if (arcSize > 0) {
uint64_t arcMin = 0;
if ((token = memmem(p, (size_t) nRead, "\nc_min ", strlen("\nc_min "))) != NULL) {
arcMin = (uint64_t) strtoull(token + 1 + dataOffset, NULL, 10);
if (arcSize > arcMin) {
arcSize -= arcMin;
if (ram->bytesUsed > arcSize) {
ram->bytesUsed -= arcSize;
}
}
}
}
}
}
}
}
return NULL;
}
+6
View File
@@ -14,5 +14,11 @@ const char* ffDetectMemory(FFMemoryResult* ram) {
ram->bytesTotal = (uint64_t) buf.npages * instance.state.platform.sysinfo.pageSize;
ram->bytesUsed = ((uint64_t) buf.active + (uint64_t) buf.inactive + (uint64_t) buf.wired) * instance.state.platform.sysinfo.pageSize;
int64_t bytesArc = ffSysctlGetInt64("kstat.zfs.misc.arcstats.size", 0);
if (bytesArc > 0) bytesArc -= ffSysctlGetInt64("kstat.zfs.misc.arcstats.c_min", 0);
if (bytesArc > 0 && (uint64_t) bytesArc < ram->bytesUsed) {
ram->bytesUsed -= (uint64_t) bytesArc;
}
return NULL;
}
+36 -2
View File
@@ -1,9 +1,43 @@
#include "memory.h"
#include <unistd.h>
#include <kstat.h>
static inline void kstatFreeWrap(kstat_ctl_t** pkc) {
assert(pkc);
if (*pkc) {
kstat_close(*pkc);
}
}
const char* ffDetectMemory(FFMemoryResult* ram) {
ram->bytesTotal = (uint64_t) sysconf(_SC_PHYS_PAGES) * instance.state.platform.sysinfo.pageSize;
ram->bytesUsed = ram->bytesTotal - (uint64_t) sysconf(_SC_AVPHYS_PAGES) * instance.state.platform.sysinfo.pageSize;
uint64_t pageSize = instance.state.platform.sysinfo.pageSize;
ram->bytesTotal = (uint64_t) sysconf(_SC_PHYS_PAGES) * pageSize;
ram->bytesUsed = ram->bytesTotal - (uint64_t) sysconf(_SC_AVPHYS_PAGES) * pageSize;
FF_A_CLEANUP(kstatFreeWrap) kstat_ctl_t* kc = kstat_open();
if (kc != NULL) {
kstat_t* ksp = kstat_lookup(kc, "zfs", -1, "arcstats");
if (ksp != NULL && kstat_read(kc, ksp, NULL) != -1) {
kstat_named_t* kn_size = (kstat_named_t*) kstat_data_lookup(ksp, "size");
kstat_named_t* kn_cmin = (kstat_named_t*) kstat_data_lookup(ksp, "c_min");
if (kn_size != NULL && kn_cmin != NULL &&
kn_size->data_type == KSTAT_DATA_UINT64 &&
kn_cmin->data_type == KSTAT_DATA_UINT64) {
uint64_t arcSize = kn_size->value.ui64;
uint64_t arcMin = kn_cmin->value.ui64;
if (arcSize > arcMin) {
uint64_t reclaimableArc = arcSize - arcMin;
if (ram->bytesUsed > reclaimableArc) {
ram->bytesUsed -= reclaimableArc;
}
}
}
}
}
return NULL;
}
+17 -3
View File
@@ -9,12 +9,12 @@ static const FFlogo C[] = {
.names = { "CachyOS" },
.lines = FASTFETCH_DATATEXT_LOGO_CACHYOS,
.colors = {
FF_COLOR_FG_CYAN,
FF_COLOR_FG_GREEN,
FF_COLOR_FG_CYAN,
FF_COLOR_FG_BLACK,
},
.colorKeys = FF_COLOR_FG_CYAN,
.colorTitle = FF_COLOR_FG_CYAN,
.colorTitle = FF_COLOR_FG_GREEN,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_CACHYOS_SMALL
@@ -24,10 +24,24 @@ static const FFlogo C[] = {
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_CACHYOS_SMALL,
.colors = {
FF_COLOR_FG_GREEN,
FF_COLOR_FG_CYAN,
},
.colorKeys = FF_COLOR_FG_CYAN,
.colorTitle = FF_COLOR_FG_CYAN,
.colorTitle = FF_COLOR_FG_GREEN,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_CACHYOS_OLD_SMALL
// CachyOSOldSmall
{
.names = { "CachyOS_old_small" },
.type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_CACHYOS_OLD_SMALL,
.colors = {
FF_COLOR_FG_CYAN,
},
.colorKeys = FF_COLOR_FG_CYAN,
.colorTitle = FF_COLOR_FG_GREEN,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_CALCULATE
+8
View File
@@ -0,0 +1,8 @@
/''''''''''''/
/''''''''''''/
/''''''/
/''''''/
\......\
\......\
\.............../
\............./
+11 -8
View File
@@ -1,8 +1,11 @@
/''''''''''''/
/''''''''''''/
/''''''/
/''''''/
\......\
\......\
\.............../
\............./
...........
$2/,,,,$1...../
$2/,,,$1..$2,,$1../ $2()
$2/,,,,$1../
$2/,,,$1.../ $1/'\
$2/,$1...../ $2\,/
$2\,,,,,,\\ $1_
$2\,,$1....\\ $1/ \
$1\...$2,$1..\\ $2\_/
$1\..$2,,,,,,,,,,,,/
$1\$2,,$1........$2,,/
+12
View File
@@ -122,6 +122,18 @@ static const FFlogo T[] = {
.colorTitle = FF_COLOR_FG_256 "32",
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_TURKISH
// Turkish
{
.names = { "Turkish", },
.lines = FASTFETCH_DATATEXT_LOGO_TURKISH,
.colors = {
FF_COLOR_FG_DEFAULT,
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_RED,
},
#endif
#ifdef FASTFETCH_DATATEXT_LOGO_TUXEDO_OS
// TuxedoOS
{
+20
View File
@@ -0,0 +1,20 @@
@@@@@@@@@
@@@@@@ @@
@@@@@
@@@@@
@@@@@@
@@@@@ @@@@@
@@@@@@ @@@@@@@@@@@@@
@@@@@@@ @@ @@@@@@ @
@@@@@@@@@@@ @@@@@
@@@@
@@@@
@@@@@@@@@@ @@@@@
@@@@@@@ @@ @@@@@@ @
@@@@@@ @@@@@@@@@@@@@
@@@@@ @@@@@@@
@@@@@@
@@@@@
@@@@@
@@@@@@ @@
@@@@@@@@@@