aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-02-18 15:27:44 +0000
committerRon Yorston <rmy@pobox.com>2021-02-18 15:47:47 +0000
commit2b8770720868c750ad8609df4041337eb2c6cf71 (patch)
tree85aff1e2b748d0e75ee5dbe82bc574bb2a5a9c1b
parent2d20b9d88c4fc91637babaafa4a60dd7943e03a7 (diff)
downloadbusybox-w32-2b8770720868c750ad8609df4041337eb2c6cf71.tar.gz
busybox-w32-2b8770720868c750ad8609df4041337eb2c6cf71.tar.bz2
busybox-w32-2b8770720868c750ad8609df4041337eb2c6cf71.zip
free: implement sysinfo(2) and enable free(1)
This is an experimental implementation of sysinfo(2)/free(1). It uses the WIN32 API GlobalMemoryStatusEx() to obtain information about memory. It seems that the 'total pagefile' value includes total RAM as well as pagefile and 'available pagefile' includes available RAM. So the RAM values are deducted. I've no idea what corresponds to Linux buffers and cache.
-rw-r--r--configs/mingw32_defconfig2
-rw-r--r--configs/mingw64_defconfig2
-rw-r--r--include/mingw.h22
-rw-r--r--procps/free.c15
-rw-r--r--win32/mingw.c24
5 files changed, 63 insertions, 2 deletions
diff --git a/configs/mingw32_defconfig b/configs/mingw32_defconfig
index 7108c2dda..8c0e2ed42 100644
--- a/configs/mingw32_defconfig
+++ b/configs/mingw32_defconfig
@@ -1035,7 +1035,7 @@ CONFIG_FEATURE_MIME_CHARSET=""
1035# 1035#
1036# Process Utilities 1036# Process Utilities
1037# 1037#
1038# CONFIG_FREE is not set 1038CONFIG_FREE=y
1039# CONFIG_FUSER is not set 1039# CONFIG_FUSER is not set
1040# CONFIG_IOSTAT is not set 1040# CONFIG_IOSTAT is not set
1041CONFIG_KILL=y 1041CONFIG_KILL=y
diff --git a/configs/mingw64_defconfig b/configs/mingw64_defconfig
index 0cb4f4a3e..89167b998 100644
--- a/configs/mingw64_defconfig
+++ b/configs/mingw64_defconfig
@@ -1035,7 +1035,7 @@ CONFIG_FEATURE_MIME_CHARSET=""
1035# 1035#
1036# Process Utilities 1036# Process Utilities
1037# 1037#
1038# CONFIG_FREE is not set 1038CONFIG_FREE=y
1039# CONFIG_FUSER is not set 1039# CONFIG_FUSER is not set
1040# CONFIG_IOSTAT is not set 1040# CONFIG_IOSTAT is not set
1041CONFIG_KILL=y 1041CONFIG_KILL=y
diff --git a/include/mingw.h b/include/mingw.h
index f16d086e2..c2a8b61bf 100644
--- a/include/mingw.h
+++ b/include/mingw.h
@@ -349,6 +349,28 @@ int mingw_fstat(int fd, struct mingw_stat *buf);
349#define fstat mingw_fstat 349#define fstat mingw_fstat
350 350
351/* 351/*
352 * sys/sysinfo.h
353 */
354struct sysinfo {
355 long uptime; /* Seconds since boot */
356 unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
357 unsigned long totalram; /* Total usable main memory size */
358 unsigned long freeram; /* Available memory size */
359 unsigned long sharedram; /* Amount of shared memory */
360 unsigned long bufferram; /* Memory used by buffers */
361 unsigned long totalswap; /* Total swap space size */
362 unsigned long freeswap; /* Swap space still available */
363 unsigned short procs; /* Number of current processes */
364 unsigned long totalhigh; /* Total high memory size */
365 unsigned long freehigh; /* Available high memory size */
366 unsigned int mem_unit; /* Memory unit size in bytes */
367 char _f[20-2*sizeof(long)-sizeof(int)];
368 /* Padding to 64 bytes */
369};
370
371int sysinfo(struct sysinfo *info);
372
373/*
352 * sys/sysmacros.h 374 * sys/sysmacros.h
353 */ 375 */
354#define makedev(a,b) 0*(a)*(b) /* avoid unused warning */ 376#define makedev(a,b) 0*(a)*(b) /* avoid unused warning */
diff --git a/procps/free.c b/procps/free.c
index 0adef501f..142786083 100644
--- a/procps/free.c
+++ b/procps/free.c
@@ -52,6 +52,7 @@ static unsigned long long scale(struct globals *g, unsigned long d)
52 return ((unsigned long long)d * g->mem_unit) >> G_unit_steps; 52 return ((unsigned long long)d * g->mem_unit) >> G_unit_steps;
53} 53}
54 54
55#if !ENABLE_PLATFORM_MINGW32
55/* NOINLINE reduces main() stack usage, which makes code smaller (on x86 at least) */ 56/* NOINLINE reduces main() stack usage, which makes code smaller (on x86 at least) */
56static NOINLINE unsigned int parse_meminfo(struct globals *g) 57static NOINLINE unsigned int parse_meminfo(struct globals *g)
57{ 58{
@@ -78,6 +79,14 @@ static NOINLINE unsigned int parse_meminfo(struct globals *g)
78 79
79 return seen_cached_and_available_and_reclaimable == 0; 80 return seen_cached_and_available_and_reclaimable == 0;
80} 81}
82#else
83static NOINLINE unsigned int parse_meminfo(struct globals *g)
84{
85 g->cached_kb = g->available_kb = g->reclaimable_kb = 0;
86
87 return 1;
88}
89#endif
81 90
82int free_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 91int free_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
83int free_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM)) 92int free_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM))
@@ -135,9 +144,15 @@ int free_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM))
135 } 144 }
136#endif 145#endif
137 146
147#if !ENABLE_PLATFORM_MINGW32
138#define FIELDS_6 "%12llu %11llu %11llu %11llu %11llu %11llu\n" 148#define FIELDS_6 "%12llu %11llu %11llu %11llu %11llu %11llu\n"
139#define FIELDS_3 (FIELDS_6 + 6 + 7 + 7) 149#define FIELDS_3 (FIELDS_6 + 6 + 7 + 7)
140#define FIELDS_2 (FIELDS_6 + 6 + 7 + 7 + 7) 150#define FIELDS_2 (FIELDS_6 + 6 + 7 + 7 + 7)
151#else
152#define FIELDS_6 "%12I64u %11I64u %11I64u %11I64u %11I64u %11I64u\n"
153#define FIELDS_3 (FIELDS_6 + 7 + 8 + 8)
154#define FIELDS_2 (FIELDS_6 + 8 + 8 + 8 + 8)
155#endif
141 156
142 printf(FIELDS_6, 157 printf(FIELDS_6,
143 scale(&G, info.totalram), //total 158 scale(&G, info.totalram), //total
diff --git a/win32/mingw.c b/win32/mingw.c
index 75635fdf1..48d2eefa7 100644
--- a/win32/mingw.c
+++ b/win32/mingw.c
@@ -1368,6 +1368,30 @@ int mingw_unlink(const char *pathname)
1368 return ret; 1368 return ret;
1369} 1369}
1370 1370
1371int sysinfo(struct sysinfo *info)
1372{
1373 DECLARE_PROC_ADDR(BOOL, GlobalMemoryStatusEx, LPMEMORYSTATUSEX);
1374 MEMORYSTATUSEX mem;
1375
1376 memset((void *)info, 0, sizeof(struct sysinfo));
1377
1378 if (!INIT_PROC_ADDR(kernel32.dll, GlobalMemoryStatusEx)) {
1379 return -1;
1380 }
1381
1382 mem.dwLength = sizeof(MEMORYSTATUSEX);
1383 if (!GlobalMemoryStatusEx(&mem))
1384 return -1;
1385
1386 info->mem_unit = 1;
1387 info->totalram = mem.ullTotalPhys;
1388 info->freeram = mem.ullAvailPhys;
1389 info->totalswap = mem.ullTotalPageFile - mem.ullTotalPhys;
1390 info->freeswap = mem.ullAvailPageFile - mem.ullAvailPhys;
1391
1392 return 0;
1393}
1394
1371#undef strftime 1395#undef strftime
1372size_t mingw_strftime(char *buf, size_t max, const char *format, const struct tm *tm) 1396size_t mingw_strftime(char *buf, size_t max, const char *format, const struct tm *tm)
1373{ 1397{