aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-02-23 08:23:16 +0000
committerRon Yorston <rmy@pobox.com>2021-02-23 09:00:04 +0000
commitd7c6685d352371dd9becd0ad21d250a02c3323ab (patch)
treeb5d74710972ad38610fa6b8504527c17168a5f48
parent379e128a3a4f5343cbd4a9f1be3538cf76af82e2 (diff)
downloadbusybox-w32-d7c6685d352371dd9becd0ad21d250a02c3323ab.tar.gz
busybox-w32-d7c6685d352371dd9becd0ad21d250a02c3323ab.tar.bz2
busybox-w32-d7c6685d352371dd9becd0ad21d250a02c3323ab.zip
win32: update sysinfo(2) implementation (again)
Use another API call: EnumPageFiles(). This seems to provide more reliable information about page file usage than the previous ad hoc method. It also allows the call to GlobalMemoryStatusEx() to be removed. With these changes free(1) works sensibly on Windows XP, though not ReactOS.
-rw-r--r--win32/mingw.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/win32/mingw.c b/win32/mingw.c
index 73179dac9..b01198bd2 100644
--- a/win32/mingw.c
+++ b/win32/mingw.c
@@ -1369,15 +1369,33 @@ int mingw_unlink(const char *pathname)
1369 return ret; 1369 return ret;
1370} 1370}
1371 1371
1372struct pagefile_info {
1373 SIZE_T total;
1374 SIZE_T in_use;
1375};
1376
1377static BOOL CALLBACK
1378pagefile_cb(LPVOID context, PENUM_PAGE_FILE_INFORMATION info,
1379 LPCSTR name UNUSED_PARAM)
1380{
1381 struct pagefile_info *pfinfo = (struct pagefile_info *)context;
1382
1383 pfinfo->total += info->TotalSize;
1384 pfinfo->in_use += info->TotalInUse;
1385 return TRUE;
1386}
1387
1372int sysinfo(struct sysinfo *info) 1388int sysinfo(struct sysinfo *info)
1373{ 1389{
1374 DECLARE_PROC_ADDR(BOOL, GlobalMemoryStatusEx, LPMEMORYSTATUSEX);
1375 DECLARE_PROC_ADDR(BOOL, GetPerformanceInfo, PPERFORMANCE_INFORMATION, DWORD);
1376 MEMORYSTATUSEX mem;
1377 PERFORMANCE_INFORMATION perf; 1390 PERFORMANCE_INFORMATION perf;
1391 struct pagefile_info pfinfo;
1392 DECLARE_PROC_ADDR(BOOL, GetPerformanceInfo, PPERFORMANCE_INFORMATION,
1393 DWORD);
1394 DECLARE_PROC_ADDR(BOOL, EnumPageFilesA, PENUM_PAGE_FILE_CALLBACKA, LPVOID);
1378 1395
1379 memset((void *)info, 0, sizeof(struct sysinfo)); 1396 memset((void *)info, 0, sizeof(struct sysinfo));
1380 memset((void *)&perf, 0, sizeof(PERFORMANCE_INFORMATION)); 1397 memset((void *)&perf, 0, sizeof(PERFORMANCE_INFORMATION));
1398 memset((void *)&pfinfo, 0, sizeof(struct pagefile_info));
1381 info->mem_unit = 4096; 1399 info->mem_unit = 4096;
1382 1400
1383 if (INIT_PROC_ADDR(psapi.dll, GetPerformanceInfo)) { 1401 if (INIT_PROC_ADDR(psapi.dll, GetPerformanceInfo)) {
@@ -1385,19 +1403,18 @@ int sysinfo(struct sysinfo *info)
1385 GetPerformanceInfo(&perf, perf.cb); 1403 GetPerformanceInfo(&perf, perf.cb);
1386 } 1404 }
1387 1405
1388 if (INIT_PROC_ADDR(kernel32.dll, GlobalMemoryStatusEx)) { 1406 if (INIT_PROC_ADDR(psapi.dll, EnumPageFilesA)) {
1389 mem.dwLength = sizeof(MEMORYSTATUSEX); 1407 EnumPageFilesA((PENUM_PAGE_FILE_CALLBACK)pagefile_cb, (LPVOID)&pfinfo);
1390 if (GlobalMemoryStatusEx(&mem)) {
1391 info->totalram = mem.ullTotalPhys >> 12;
1392 info->bufferram = (perf.SystemCache * perf.PageSize) >> 12;
1393 if ((mem.ullAvailPhys >> 12) > info->bufferram)
1394 info->freeram = (mem.ullAvailPhys >> 12) - info->bufferram;
1395 info->totalswap = (mem.ullTotalPageFile - mem.ullTotalPhys) >> 12;
1396 if (mem.ullAvailPageFile > mem.ullAvailPhys)
1397 info->freeswap = (mem.ullAvailPageFile-mem.ullAvailPhys) >> 12;
1398 }
1399 } 1408 }
1400 1409
1410 info->totalram = perf.PhysicalTotal * perf.PageSize / 4096;
1411 info->bufferram = perf.SystemCache * perf.PageSize / 4096;
1412 if (perf.PhysicalAvailable > perf.SystemCache)
1413 info->freeram = perf.PhysicalAvailable * perf.PageSize / 4096 -
1414 info->bufferram;
1415 info->totalswap = pfinfo.total * perf.PageSize / 4096;
1416 info->freeswap = (pfinfo.total - pfinfo.in_use) * perf.PageSize / 4096;
1417
1401 info->uptime = GetTickCount64() / 1000; 1418 info->uptime = GetTickCount64() / 1000;
1402 info->procs = perf.ProcessCount; 1419 info->procs = perf.ProcessCount;
1403 1420