Platform: replaces pageSize for pageSizeShift

This commit is contained in:
李通洲
2026-09-20 20:55:57 +08:00
parent 3bfc4ec674
commit 39564acde4
22 changed files with 55 additions and 59 deletions
+4 -1
View File
@@ -8,7 +8,10 @@ typedef struct FFPlatformSysinfo {
FFstrbuf release;
FFstrbuf version;
FFstrbuf architecture;
uint32_t pageSize;
// The base-2 logarithm of the memory page size, i.e. a page is `1 << pageSizeShift` bytes.
// Page sizes are powers of two on every supported platform. Storing the exponent instead of
// the byte count keeps page count arithmetic in 64 bits and makes the invariant explicit.
uint32_t pageSizeShift;
} FFPlatformSysinfo;
typedef struct FFPlatform {
+1 -1
View File
@@ -27,7 +27,7 @@ void ffPlatformInit(FFPlatform* platform) {
ffStrbufInit(&info->release);
ffStrbufInit(&info->version);
ffStrbufInit(&info->architecture);
info->pageSize = 0;
info->pageSizeShift = 12; // 4096, reasonable fallback
ffPlatformInitImpl(platform);
+4 -6
View File
@@ -319,12 +319,10 @@ static void getSysinfo(FFPlatformSysinfo* info, const struct utsname* uts) {
#endif
ffStrbufAppendS(&info->architecture, uts->machine);
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__)
size_t length = sizeof(info->pageSize);
sysctl((int[]) { CTL_HW, HW_PAGESIZE }, 2, &info->pageSize, &length, nullptr, 0);
#else
info->pageSize = (uint32_t) sysconf(_SC_PAGESIZE);
#endif
// _SC_PAGESIZE is one of the sysconf names <unistd.h> requires every implementation to define,
// and the only failure POSIX defines for sysconf is an invalid name, so this does not fail.
// It replaces the former sysctl(CTL_HW, HW_PAGESIZE) call on FreeBSD / macOS / OpenBSD / NetBSD.
info->pageSizeShift = (uint32_t) __builtin_ctzl((unsigned long) sysconf(_SC_PAGESIZE));
}
static void getCwd(FFPlatform* platform) {
+1 -3
View File
@@ -229,9 +229,7 @@ static void getSystemReleaseAndVersion(FFPlatformSysinfo* info) {
static void getSystemPageSize(FFPlatformSysinfo* info) {
SYSTEM_BASIC_INFORMATION sbi;
if (NT_SUCCESS(NtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), nullptr))) {
info->pageSize = sbi.PhysicalPageSize;
} else {
info->pageSize = 4096;
info->pageSizeShift = (uint32_t) __builtin_ctzl(sbi.PhysicalPageSize);
}
}
+1 -1
View File
@@ -211,7 +211,7 @@ static bool readPhysicalMemory(int fd, off_t address, size_t length, void* buffe
}
#endif
off_t alignedAddress = address & ~((off_t) instance.state.platform.sysinfo.pageSize - 1);
off_t alignedAddress = address & ~(((off_t) 1 << instance.state.platform.sysinfo.pageSizeShift) - 1);
size_t pageOffset = (size_t) (address - alignedAddress);
size_t mapLength = pageOffset + length;
+1 -1
View File
@@ -29,7 +29,7 @@ const char* ffDetectMemory(FFMemoryResult* ram) {
uint64_t pagesFree = vmstat.free_count - vmstat.speculative_count;
uint64_t pagesFileBacked = vmstat.external_page_count; // Cached files
ram->bytesUsed = ram->bytesTotal - (pagesFree + pagesFileBacked) * instance.state.platform.sysinfo.pageSize;
ram->bytesUsed = ram->bytesTotal - ((pagesFree + pagesFileBacked) << instance.state.platform.sysinfo.pageSizeShift);
return nullptr;
}
+1 -1
View File
@@ -11,7 +11,7 @@ const char* ffDetectMemory(FFMemoryResult* ram) {
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 - (uint64_t) bytesCache;
ram->bytesUsed = ram->bytesTotal - ((uint64_t) pagesFree << instance.state.platform.sysinfo.pageSizeShift) - (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);
+3 -3
View File
@@ -8,9 +8,9 @@ const char* ffDetectMemory(FFMemoryResult* ram) {
return "Error getting system info";
}
uint32_t pageSize = instance.state.platform.sysinfo.pageSize;
ram->bytesTotal = pageSize * info.max_pages;
ram->bytesUsed = pageSize * info.used_pages;
const uint32_t pageSizeShift = instance.state.platform.sysinfo.pageSizeShift;
ram->bytesTotal = (uint64_t) info.max_pages << pageSizeShift;
ram->bytesUsed = (uint64_t) info.used_pages << pageSizeShift;
return nullptr;
}
+2 -2
View File
@@ -11,8 +11,8 @@ const char* ffDetectMemory(FFMemoryResult* ram) {
return "sysctl(CTL_VM, VM_UVMEXP2) failed";
}
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;
ram->bytesTotal = (uint64_t) buf.npages << instance.state.platform.sysinfo.pageSizeShift;
ram->bytesUsed = ((uint64_t) buf.active + (uint64_t) buf.inactive + (uint64_t) buf.wired) << instance.state.platform.sysinfo.pageSizeShift;
int64_t bytesArc = ffSysctlGetInt64("kstat.zfs.misc.arcstats.size", 0);
if (bytesArc > 0) bytesArc -= ffSysctlGetInt64("kstat.zfs.misc.arcstats.c_min", 0);
+2 -2
View File
@@ -11,8 +11,8 @@ const char* ffDetectMemory(FFMemoryResult* ram) {
return "sysctl(CTL_VM, VM_UVMEXP) failed";
}
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;
ram->bytesTotal = (uint64_t) buf.npages << instance.state.platform.sysinfo.pageSizeShift;
ram->bytesUsed = ((uint64_t) buf.active + (uint64_t) buf.inactive + (uint64_t) buf.wired) << instance.state.platform.sysinfo.pageSizeShift;
return nullptr;
}
+3 -3
View File
@@ -10,10 +10,10 @@ static inline void kstatFreeWrap(kstat_ctl_t** pkc) {
}
const char* ffDetectMemory(FFMemoryResult* ram) {
uint64_t pageSize = instance.state.platform.sysinfo.pageSize;
const uint32_t pageSizeShift = instance.state.platform.sysinfo.pageSizeShift;
ram->bytesTotal = (uint64_t) sysconf(_SC_PHYS_PAGES) * pageSize;
ram->bytesUsed = ram->bytesTotal - (uint64_t) sysconf(_SC_AVPHYS_PAGES) * pageSize;
ram->bytesTotal = (uint64_t) sysconf(_SC_PHYS_PAGES) << pageSizeShift;
ram->bytesUsed = ram->bytesTotal - ((uint64_t) sysconf(_SC_AVPHYS_PAGES) << pageSizeShift);
[[gnu::cleanup(kstatFreeWrap)]] kstat_ctl_t* kc = kstat_open();
if (kc != nullptr) {
+3 -3
View File
@@ -19,8 +19,8 @@ const char* ffDetectMemory(FFMemoryResult* ram) {
SharedUserData->NumberOfPhysicalPages;
#endif
uint64_t pageSize = instance.state.platform.sysinfo.pageSize;
ram->bytesTotal = phyPages * pageSize;
ram->bytesUsed = (phyPages - sbpi.AvailablePages) * pageSize;
uint64_t pageSizeShift = instance.state.platform.sysinfo.pageSizeShift;
ram->bytesTotal = phyPages << pageSizeShift;
ram->bytesUsed = (phyPages - sbpi.AvailablePages) << pageSizeShift;
return nullptr;
}
+7 -7
View File
@@ -5,7 +5,7 @@
#include <sys/stat.h>
#include <sys/param.h>
static void addSwapEntry(FFlist* result, struct xswdev* xsw, uint32_t pageSize) {
static void addSwapEntry(FFlist* result, struct xswdev* xsw, uint32_t pageSizeShift) {
if (xsw->xsw_nblks == 0) { // DFBSD reports some /dev/wdog devices with nblks == 0
return;
}
@@ -16,8 +16,8 @@ static void addSwapEntry(FFlist* result, struct xswdev* xsw, uint32_t pageSize)
} else {
ffStrbufInitF(&swap->name, "/dev/%s", devname(xsw->xsw_dev, S_IFCHR));
}
swap->bytesUsed = (uint64_t) xsw->xsw_used * pageSize;
swap->bytesTotal = (uint64_t) xsw->xsw_nblks * pageSize;
swap->bytesUsed = (uint64_t) xsw->xsw_used << pageSizeShift;
swap->bytesTotal = (uint64_t) xsw->xsw_nblks << pageSizeShift;
}
#if __DragonFly__
@@ -29,7 +29,7 @@ const char* ffDetectSwap(FFlist* result) {
return "sysctlbyname(\"vm.swap_info_array\") failed";
}
uint32_t pageSize = instance.state.platform.sysinfo.pageSize;
const uint32_t pageSizeShift = instance.state.platform.sysinfo.pageSizeShift;
size_t count = size / sizeof(struct xswdev);
if (count == 0) {
@@ -41,7 +41,7 @@ const char* ffDetectSwap(FFlist* result) {
}
for (uint32_t i = 0; i < count; ++i) {
addSwapEntry(result, &xsws[i], pageSize);
addSwapEntry(result, &xsws[i], pageSizeShift);
}
return nullptr;
@@ -56,7 +56,7 @@ const char* ffDetectSwap(FFlist* result) {
return "sysctlnametomib(\"vm.swap_info\") failed";
}
uint32_t pageSize = instance.state.platform.sysinfo.pageSize;
const uint32_t pageSizeShift = instance.state.platform.sysinfo.pageSizeShift;
for (int n = 0;; ++n) {
mib[mibsize] = n;
@@ -69,7 +69,7 @@ const char* ffDetectSwap(FFlist* result) {
return "xswdev version mismatch";
}
addSwapEntry(result, &xsw, pageSize);
addSwapEntry(result, &xsw, pageSizeShift);
}
return nullptr;
+3 -3
View File
@@ -9,7 +9,7 @@ const char* ffDetectSwap(FFlist* result) {
return "Error getting system info";
}
uint32_t pageSize = instance.state.platform.sysinfo.pageSize;
const uint32_t pageSizeShift = instance.state.platform.sysinfo.pageSizeShift;
FFSwapResult* swap = FF_LIST_ADD(FFSwapResult, *result);
ffStrbufInitStatic(&swap->name, "System");
void* kvms = load_driver_settings("virtual_memory"); // /boot/home/config/settings/kernel/drivers/virtual_memory
@@ -20,8 +20,8 @@ const char* ffDetectSwap(FFlist* result) {
}
unload_driver_settings(kvms);
}
swap->bytesTotal = pageSize * (uint64_t) info.max_swap_pages;
swap->bytesUsed = pageSize * (uint64_t) (info.max_swap_pages - info.free_swap_pages);
swap->bytesTotal = (uint64_t) info.max_swap_pages << pageSizeShift;
swap->bytesUsed = (uint64_t) (info.max_swap_pages - info.free_swap_pages) << pageSizeShift;
return nullptr;
}
+3 -3
View File
@@ -20,12 +20,12 @@ const char* ffDetectSwap(FFlist* result) {
return "swapctl() failed";
}
uint32_t pageSize = instance.state.platform.sysinfo.pageSize;
const uint32_t pageSizeShift = instance.state.platform.sysinfo.pageSizeShift;
for (int i = 0; i < size; ++i) {
FFSwapResult* swap = FF_LIST_ADD(FFSwapResult, *result);
ffStrbufInitS(&swap->name, table->swt_ent[i].ste_path);
swap->bytesTotal = (uint64_t) table->swt_ent[i].ste_pages * pageSize;
swap->bytesUsed = swap->bytesTotal - (uint64_t) table->swt_ent[i].ste_free * pageSize;
swap->bytesTotal = (uint64_t) table->swt_ent[i].ste_pages << pageSizeShift;
swap->bytesUsed = swap->bytesTotal - ((uint64_t) table->swt_ent[i].ste_free << pageSizeShift);
}
return nullptr;
+3 -3
View File
@@ -18,15 +18,15 @@ const char* ffDetectSwap(FFlist* result) {
return nullptr;
}
uint32_t pageSize = instance.state.platform.sysinfo.pageSize;
const uint32_t pageSizeShift = instance.state.platform.sysinfo.pageSizeShift;
for (SYSTEM_PAGEFILE_INFORMATION* current = pstart;; current = (SYSTEM_PAGEFILE_INFORMATION*) ((uint8_t*) current + current->NextEntryOffset)) {
FFSwapResult* swap = FF_LIST_ADD(FFSwapResult, *result);
ffStrbufInitNWS(&swap->name, current->FileName.Length / sizeof(wchar_t), current->FileName.Buffer);
if (ffStrbufStartsWithS(&swap->name, "\\??\\")) {
ffStrbufSubstrAfter(&swap->name, strlen("\\??\\") - 1);
}
swap->bytesUsed = (uint64_t) current->TotalUsed * pageSize;
swap->bytesTotal = (uint64_t) current->CurrentSize * pageSize;
swap->bytesUsed = (uint64_t) current->TotalUsed << pageSizeShift;
swap->bytesTotal = (uint64_t) current->CurrentSize << pageSizeShift;
if (current->NextEntryOffset == 0) {
break;
}
+2 -2
View File
@@ -22,7 +22,7 @@ const char* ffTopGetProcessSnapshot(FFlist* snapshots, [[maybe_unused]] FFTopTyp
}
uint32_t count = (uint32_t) (length / sizeof(struct kinfo_proc));
uint32_t pageSize = instance.state.platform.sysinfo.pageSize;
const uint32_t pageSizeShift = instance.state.platform.sysinfo.pageSizeShift;
for (uint32_t i = 0; i < count; ++i) {
const struct kinfo_proc* proc = &processes[i];
@@ -44,7 +44,7 @@ const char* ffTopGetProcessSnapshot(FFlist* snapshots, [[maybe_unused]] FFTopTyp
(uint64_t) proc->ki_rusage.ru_stime.tv_usec / 1000;
item->cpuTime = userMs + sysMs;
item->memBytes = (uint64_t) proc->ki_rssize * (uint64_t) pageSize;
item->memBytes = (uint64_t) proc->ki_rssize << pageSizeShift;
item->startTime = (uint64_t) proc->ki_start.tv_sec * 1000 +
(uint64_t) proc->ki_start.tv_usec / 1000;
+2 -2
View File
@@ -23,7 +23,7 @@ const char* ffTopGetProcessSnapshot(FFlist* snapshots, FFTopTypes showTypes) {
}
uint32_t count = (uint32_t) (length / sizeof(struct kinfo_proc));
uint32_t pageSize = instance.state.platform.sysinfo.pageSize;
const uint32_t pageSizeShift = instance.state.platform.sysinfo.pageSizeShift;
for (uint32_t i = 0; i < count; ++i) {
const struct kinfo_proc* proc = &processes[i];
@@ -45,7 +45,7 @@ const char* ffTopGetProcessSnapshot(FFlist* snapshots, FFTopTypes showTypes) {
uint64_t liveMs = (proc->kp_lwp.kl_uticks + proc->kp_lwp.kl_sticks) / 1000;
item->cpuTime = exitedMs + liveMs;
item->memBytes = (uint64_t) proc->kp_vm_rssize * pageSize;
item->memBytes = (uint64_t) proc->kp_vm_rssize << pageSizeShift;
item->startTime = (uint64_t) proc->kp_start.tv_sec * 1000 +
(uint64_t) proc->kp_start.tv_usec / 1000;
+3 -6
View File
@@ -69,11 +69,8 @@ static bool parseStat(const char* buffer, size_t length, FFTopProcessSnapshot* r
const char* ffTopGetProcessSnapshot(FFlist* snapshots, FFTopTypes showTypes) {
const long ticks = sysconf(_SC_CLK_TCK);
const long pageSize = instance.state.platform.sysinfo.pageSize;
FF_DEBUG("Scanning /proc: clk_tck=%ld, pageSize=%ld", ticks, pageSize);
if (ticks <= 0 || pageSize <= 0) {
return "sysconf(_SC_CLK_TCK or _SC_PAGESIZE) failed";
}
const uint32_t pageSizeShift = instance.state.platform.sysinfo.pageSizeShift;
FF_DEBUG("Scanning /proc: clk_tck=%ld, pageSizeShift=%u", ticks, (unsigned) pageSizeShift);
FF_AUTO_CLOSE_DIR DIR* dir = opendir("/proc");
if (!dir) {
@@ -150,7 +147,7 @@ const char* ffTopGetProcessSnapshot(FFlist* snapshots, FFTopTypes showTypes) {
}
snapshot->pid = (uint32_t) pid;
snapshot->memBytes = rssPages * (uint64_t) pageSize;
snapshot->memBytes = (uint64_t) rssPages << pageSizeShift;
snapshot->bytesRead = 0;
snapshot->bytesWritten = 0;
if (ioLength > 0) {
+2 -2
View File
@@ -23,7 +23,7 @@ const char* ffTopGetProcessSnapshot(FFlist* snapshots, FFTopTypes showTypes) {
}
uint32_t count = (uint32_t) (length / sizeof(struct kinfo_proc2));
uint32_t pageSize = instance.state.platform.sysinfo.pageSize;
const uint32_t pageSizeShift = instance.state.platform.sysinfo.pageSizeShift;
for (uint32_t i = 0; i < count; ++i) {
const struct kinfo_proc2* proc = &processes[i];
@@ -43,7 +43,7 @@ const char* ffTopGetProcessSnapshot(FFlist* snapshots, FFTopTypes showTypes) {
(uint64_t) proc->p_ustime_usec / 1000;
item->cpuTime = userMs + sysMs;
item->memBytes = (uint64_t) proc->p_vm_rssize * (uint64_t) pageSize;
item->memBytes = (uint64_t) proc->p_vm_rssize << pageSizeShift;
item->startTime = (uint64_t) proc->p_ustart_sec * 1000 +
(uint64_t) proc->p_ustart_usec / 1000;
+2 -2
View File
@@ -21,7 +21,7 @@ const char* ffTopGetProcessSnapshot(FFlist* snapshots, FFTopTypes showTypes) {
}
int count = (int) (length / sizeof(struct kinfo_proc));
const uint32_t pageSize = instance.state.platform.sysinfo.pageSize;
const uint32_t pageSizeShift = instance.state.platform.sysinfo.pageSizeShift;
for (int i = 0; i < count; ++i) {
const struct kinfo_proc* proc = &processes[i];
@@ -35,7 +35,7 @@ const char* ffTopGetProcessSnapshot(FFlist* snapshots, FFTopTypes showTypes) {
item->pid = (uint32_t) proc->p_pid;
item->cpuTime = ((uint64_t) proc->p_uutime_sec * 1000 + (uint64_t) proc->p_uutime_usec / 1000) +
((uint64_t) proc->p_ustime_sec * 1000 + (uint64_t) proc->p_ustime_usec / 1000);
item->memBytes = (uint64_t) proc->p_vm_rssize * pageSize;
item->memBytes = (uint64_t) proc->p_vm_rssize << pageSizeShift;
item->startTime = (uint64_t) proc->p_ustart_sec * 1000 + (uint64_t) proc->p_ustart_usec / 1000;
item->bytesRead = (uint64_t) proc->p_uru_inblock * DEV_BSIZE;
item->bytesWritten = (uint64_t) proc->p_uru_oublock * DEV_BSIZE;
+2 -2
View File
@@ -11,7 +11,7 @@ bool ffPrintKernel(FFKernelOptions* options) {
printf("%s %s\n", info->name.chars, info->release.chars);
} else {
FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate();
ffSizeAppendNum(info->pageSize, &str);
ffSizeAppendNum((uint64_t) 1 << info->pageSizeShift, &str);
FF_PRINT_FORMAT_CHECKED(FF_MODULE_GET_DISPLAY_NAME(Kernel), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, ((FFformatarg[]) {
FF_ARG(info->name, "sysname"),
FF_ARG(info->release, "release"),
@@ -48,7 +48,7 @@ bool ffGenerateKernelJsonResult([[maybe_unused]] FFKernelOptions* options, yyjso
yyjson_mut_obj_add_strbuf(doc, obj, "name", &info->name);
yyjson_mut_obj_add_strbuf(doc, obj, "release", &info->release);
yyjson_mut_obj_add_strbuf(doc, obj, "version", &info->version);
yyjson_mut_obj_add_uint(doc, obj, "pageSize", info->pageSize);
yyjson_mut_obj_add_uint(doc, obj, "pageSize", (uint64_t) 1 << info->pageSizeShift);
return true;
}