free: implement -h
function old new delta
.rodata 103331 103363 +32
packed_usage 33652 33654 +2
free_main 657 588 -69
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 34/-69) Total: -35 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
diff --git a/procps/free.c b/procps/free.c
index 5683629..0b68e1b 100644
--- a/procps/free.c
+++ b/procps/free.c
@@ -19,9 +19,9 @@
//kbuild:lib-$(CONFIG_FREE) += free.o
//usage:#define free_trivial_usage
-//usage: "" IF_DESKTOP("[-bkmg]")
+//usage: "" IF_DESKTOP("[-bkmgh]")
//usage:#define free_full_usage "\n\n"
-//usage: "Display the amount of free and used system memory"
+//usage: "Display free and used memory"
//usage:
//usage:#define free_example_usage
//usage: "$ free\n"
@@ -29,6 +29,27 @@
//usage: " Mem: 257628 248724 8904 59644 93124\n"
//usage: " Swap: 128516 8404 120112\n"
//usage: "Total: 386144 257128 129016\n"
+//procps-ng 3.3.15:
+// -b, --bytes show output in bytes
+// --kilo show output in kilobytes
+// --mega show output in megabytes
+// --giga show output in gigabytes
+// --tera show output in terabytes
+// --peta show output in petabytes
+// -k, --kibi show output in kibibytes
+// -m, --mebi show output in mebibytes
+// -g, --gibi show output in gibibytes
+// --tebi show output in tebibytes
+// --pebi show output in pebibytes
+// -h, --human show human-readable output
+// --si use powers of 1000 not 1024
+// -l, --lohi show detailed low and high memory statistics
+// -t, --total show total for RAM + swap
+// -s N, --seconds N repeat printing every N seconds
+// -c N, --count N repeat printing N times, then exit
+// -w, --wide wide output
+//
+//NB: if we implement -s or -c, need to stop being NOFORK!
#include "libbb.h"
#ifdef __linux__
@@ -38,18 +59,22 @@
struct globals {
unsigned mem_unit;
#if ENABLE_DESKTOP
- uint8_t unit_steps;
-# define G_unit_steps g->unit_steps
+ unsigned unit;
+# define G_unit g->unit
#else
-# define G_unit_steps 10
+# define G_unit (1 << 10)
#endif
unsigned long cached_kb, available_kb, reclaimable_kb;
};
/* Because of NOFORK, "globals" are not in global data */
-static unsigned long long scale(struct globals *g, unsigned long d)
+static const char *scale(struct globals *g, unsigned long d)
{
- return ((unsigned long long)d * g->mem_unit) >> G_unit_steps;
+ /* Display (size * block_size) with one decimal digit.
+ * If display_unit == 0, show value no bigger than 1024 with suffix (K,M,G...),
+ * else divide by display_unit and do not use suffix.
+ * Returns "auto pointer" */
+ return make_human_readable_str(d, g->mem_unit, G_unit);
}
/* NOINLINE reduces main() stack usage, which makes code smaller (on x86 at least) */
@@ -88,20 +113,27 @@
int seen_available;
#if ENABLE_DESKTOP
- G.unit_steps = 10;
+ G.unit = 1 << 10;
if (argv[1] && argv[1][0] == '-') {
switch (argv[1][1]) {
case 'b':
- G.unit_steps = 0;
+ G.unit = 1;
break;
case 'k': /* 2^10 */
- /* G.unit_steps = 10; - already is */
+ /* G.unit = 1 << 10; - already is */
break;
case 'm': /* 2^20 */
- G.unit_steps = 20;
+ G.unit = 1 << 20;
break;
case 'g': /* 2^30 */
- G.unit_steps = 30;
+ G.unit = 1 << 30;
+ break;
+// case 't':
+// -- WRONG, -t is not "terabytes" in procps-ng, it's --total
+// G.unit = 1 << 40;
+// break;
+ case 'h':
+ G.unit = 0; /* human readable */
break;
default:
bb_show_usage();
@@ -126,23 +158,13 @@
cached += ((unsigned long long) G.reclaimable_kb * 1024) / G.mem_unit;
cached_plus_free = cached + info.freeram;
-/* In case (long long * G.mem_unit) can overflow, this can be used to reduce the chances */
-#if 0 //ENABLE_DESKTOP
- while (!(G.mem_unit & 1) && G.unit_steps != 0) {
- G.mem_unit >>= 1;
- G.unit_steps--;
- //bb_error_msg("mem_unit:%d unit_steps:%d", G.mem_unit, G.unit_steps);
- }
-#endif
-
-#define FIELDS_6 "%12llu %11llu %11llu %11llu %11llu %11llu\n"
-#define FIELDS_3 (FIELDS_6 + 6 + 7 + 7)
-#define FIELDS_2 (FIELDS_6 + 6 + 7 + 7 + 7)
-
- printf(FIELDS_6,
+ printf("%12s%12s%12s",
scale(&G, info.totalram), //total
scale(&G, info.totalram - cached_plus_free), //used
- scale(&G, info.freeram), //free
+ scale(&G, info.freeram) //free
+ );
+ /* using two printf's: only 4 auto strings are supported, we need 6 */
+ printf("%12s%12s%12s\n",
scale(&G, info.sharedram), //shared
scale(&G, cached), //buff/cache
scale(&G, available) //available
@@ -152,14 +174,14 @@
* buffer cache as free memory. */
if (!seen_available) {
printf("-/+ buffers/cache: ");
- printf(FIELDS_2,
+ printf("%12s%12s%12s\n" + 4,
scale(&G, info.totalram - cached_plus_free), //used
scale(&G, cached_plus_free) //free
);
}
#if BB_MMU
printf("Swap: ");
- printf(FIELDS_3,
+ printf("%12s%12s%12s\n",
scale(&G, info.totalswap), //total
scale(&G, info.totalswap - info.freeswap), //used
scale(&G, info.freeswap) //free