aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-06-18 12:08:02 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-06-18 12:08:02 +0200
commitdc30f3dce27bdcccb8450a2418061b4bcdc0ea14 (patch)
tree31840c006d598c7fee08796f2ba19c09d85df083
parent2c436679fbb5fa38b0e7a505022a2075fab87d84 (diff)
downloadbusybox-w32-dc30f3dce27bdcccb8450a2418061b4bcdc0ea14.tar.gz
busybox-w32-dc30f3dce27bdcccb8450a2418061b4bcdc0ea14.tar.bz2
busybox-w32-dc30f3dce27bdcccb8450a2418061b4bcdc0ea14.zip
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>
-rw-r--r--include/libbb.h4
-rw-r--r--procps/free.c80
2 files changed, 53 insertions, 31 deletions
diff --git a/include/libbb.h b/include/libbb.h
index a3f76a206..9a95a176d 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1065,10 +1065,10 @@ char *smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) FAST_
1065/* If block_size == 0, display size without fractional part, 1065/* If block_size == 0, display size without fractional part,
1066 * else display (size * block_size) with one decimal digit. 1066 * else display (size * block_size) with one decimal digit.
1067 * If display_unit == 0, show value no bigger than 1024 with suffix (K,M,G...), 1067 * If display_unit == 0, show value no bigger than 1024 with suffix (K,M,G...),
1068 * else divide by display_unit and do not use suffix. */ 1068 * else divide by display_unit and do not use suffix.
1069 * Returns "auto pointer" */
1069#define HUMAN_READABLE_MAX_WIDTH 7 /* "1024.0G" */ 1070#define HUMAN_READABLE_MAX_WIDTH 7 /* "1024.0G" */
1070#define HUMAN_READABLE_MAX_WIDTH_STR "7" 1071#define HUMAN_READABLE_MAX_WIDTH_STR "7"
1071//TODO: provide pointer to buf (avoid statics)?
1072const char *make_human_readable_str(unsigned long long size, 1072const char *make_human_readable_str(unsigned long long size,
1073 unsigned long block_size, unsigned long display_unit) FAST_FUNC; 1073 unsigned long block_size, unsigned long display_unit) FAST_FUNC;
1074/* Put a string of hex bytes ("1b2e66fe"...), return advanced pointer */ 1074/* Put a string of hex bytes ("1b2e66fe"...), return advanced pointer */
diff --git a/procps/free.c b/procps/free.c
index 568362913..0b68e1b88 100644
--- a/procps/free.c
+++ b/procps/free.c
@@ -19,9 +19,9 @@
19//kbuild:lib-$(CONFIG_FREE) += free.o 19//kbuild:lib-$(CONFIG_FREE) += free.o
20 20
21//usage:#define free_trivial_usage 21//usage:#define free_trivial_usage
22//usage: "" IF_DESKTOP("[-bkmg]") 22//usage: "" IF_DESKTOP("[-bkmgh]")
23//usage:#define free_full_usage "\n\n" 23//usage:#define free_full_usage "\n\n"
24//usage: "Display the amount of free and used system memory" 24//usage: "Display free and used memory"
25//usage: 25//usage:
26//usage:#define free_example_usage 26//usage:#define free_example_usage
27//usage: "$ free\n" 27//usage: "$ free\n"
@@ -29,6 +29,27 @@
29//usage: " Mem: 257628 248724 8904 59644 93124\n" 29//usage: " Mem: 257628 248724 8904 59644 93124\n"
30//usage: " Swap: 128516 8404 120112\n" 30//usage: " Swap: 128516 8404 120112\n"
31//usage: "Total: 386144 257128 129016\n" 31//usage: "Total: 386144 257128 129016\n"
32//procps-ng 3.3.15:
33// -b, --bytes show output in bytes
34// --kilo show output in kilobytes
35// --mega show output in megabytes
36// --giga show output in gigabytes
37// --tera show output in terabytes
38// --peta show output in petabytes
39// -k, --kibi show output in kibibytes
40// -m, --mebi show output in mebibytes
41// -g, --gibi show output in gibibytes
42// --tebi show output in tebibytes
43// --pebi show output in pebibytes
44// -h, --human show human-readable output
45// --si use powers of 1000 not 1024
46// -l, --lohi show detailed low and high memory statistics
47// -t, --total show total for RAM + swap
48// -s N, --seconds N repeat printing every N seconds
49// -c N, --count N repeat printing N times, then exit
50// -w, --wide wide output
51//
52//NB: if we implement -s or -c, need to stop being NOFORK!
32 53
33#include "libbb.h" 54#include "libbb.h"
34#ifdef __linux__ 55#ifdef __linux__
@@ -38,18 +59,22 @@
38struct globals { 59struct globals {
39 unsigned mem_unit; 60 unsigned mem_unit;
40#if ENABLE_DESKTOP 61#if ENABLE_DESKTOP
41 uint8_t unit_steps; 62 unsigned unit;
42# define G_unit_steps g->unit_steps 63# define G_unit g->unit
43#else 64#else
44# define G_unit_steps 10 65# define G_unit (1 << 10)
45#endif 66#endif
46 unsigned long cached_kb, available_kb, reclaimable_kb; 67 unsigned long cached_kb, available_kb, reclaimable_kb;
47}; 68};
48/* Because of NOFORK, "globals" are not in global data */ 69/* Because of NOFORK, "globals" are not in global data */
49 70
50static unsigned long long scale(struct globals *g, unsigned long d) 71static const char *scale(struct globals *g, unsigned long d)
51{ 72{
52 return ((unsigned long long)d * g->mem_unit) >> G_unit_steps; 73 /* Display (size * block_size) with one decimal digit.
74 * If display_unit == 0, show value no bigger than 1024 with suffix (K,M,G...),
75 * else divide by display_unit and do not use suffix.
76 * Returns "auto pointer" */
77 return make_human_readable_str(d, g->mem_unit, G_unit);
53} 78}
54 79
55/* NOINLINE reduces main() stack usage, which makes code smaller (on x86 at least) */ 80/* NOINLINE reduces main() stack usage, which makes code smaller (on x86 at least) */
@@ -88,20 +113,27 @@ int free_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM))
88 int seen_available; 113 int seen_available;
89 114
90#if ENABLE_DESKTOP 115#if ENABLE_DESKTOP
91 G.unit_steps = 10; 116 G.unit = 1 << 10;
92 if (argv[1] && argv[1][0] == '-') { 117 if (argv[1] && argv[1][0] == '-') {
93 switch (argv[1][1]) { 118 switch (argv[1][1]) {
94 case 'b': 119 case 'b':
95 G.unit_steps = 0; 120 G.unit = 1;
96 break; 121 break;
97 case 'k': /* 2^10 */ 122 case 'k': /* 2^10 */
98 /* G.unit_steps = 10; - already is */ 123 /* G.unit = 1 << 10; - already is */
99 break; 124 break;
100 case 'm': /* 2^20 */ 125 case 'm': /* 2^20 */
101 G.unit_steps = 20; 126 G.unit = 1 << 20;
102 break; 127 break;
103 case 'g': /* 2^30 */ 128 case 'g': /* 2^30 */
104 G.unit_steps = 30; 129 G.unit = 1 << 30;
130 break;
131// case 't':
132// -- WRONG, -t is not "terabytes" in procps-ng, it's --total
133// G.unit = 1 << 40;
134// break;
135 case 'h':
136 G.unit = 0; /* human readable */
105 break; 137 break;
106 default: 138 default:
107 bb_show_usage(); 139 bb_show_usage();
@@ -126,23 +158,13 @@ int free_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM))
126 cached += ((unsigned long long) G.reclaimable_kb * 1024) / G.mem_unit; 158 cached += ((unsigned long long) G.reclaimable_kb * 1024) / G.mem_unit;
127 cached_plus_free = cached + info.freeram; 159 cached_plus_free = cached + info.freeram;
128 160
129/* In case (long long * G.mem_unit) can overflow, this can be used to reduce the chances */ 161 printf("%12s%12s%12s",
130#if 0 //ENABLE_DESKTOP
131 while (!(G.mem_unit & 1) && G.unit_steps != 0) {
132 G.mem_unit >>= 1;
133 G.unit_steps--;
134 //bb_error_msg("mem_unit:%d unit_steps:%d", G.mem_unit, G.unit_steps);
135 }
136#endif
137
138#define FIELDS_6 "%12llu %11llu %11llu %11llu %11llu %11llu\n"
139#define FIELDS_3 (FIELDS_6 + 6 + 7 + 7)
140#define FIELDS_2 (FIELDS_6 + 6 + 7 + 7 + 7)
141
142 printf(FIELDS_6,
143 scale(&G, info.totalram), //total 162 scale(&G, info.totalram), //total
144 scale(&G, info.totalram - cached_plus_free), //used 163 scale(&G, info.totalram - cached_plus_free), //used
145 scale(&G, info.freeram), //free 164 scale(&G, info.freeram) //free
165 );
166 /* using two printf's: only 4 auto strings are supported, we need 6 */
167 printf("%12s%12s%12s\n",
146 scale(&G, info.sharedram), //shared 168 scale(&G, info.sharedram), //shared
147 scale(&G, cached), //buff/cache 169 scale(&G, cached), //buff/cache
148 scale(&G, available) //available 170 scale(&G, available) //available
@@ -152,14 +174,14 @@ int free_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM))
152 * buffer cache as free memory. */ 174 * buffer cache as free memory. */
153 if (!seen_available) { 175 if (!seen_available) {
154 printf("-/+ buffers/cache: "); 176 printf("-/+ buffers/cache: ");
155 printf(FIELDS_2, 177 printf("%12s%12s%12s\n" + 4,
156 scale(&G, info.totalram - cached_plus_free), //used 178 scale(&G, info.totalram - cached_plus_free), //used
157 scale(&G, cached_plus_free) //free 179 scale(&G, cached_plus_free) //free
158 ); 180 );
159 } 181 }
160#if BB_MMU 182#if BB_MMU
161 printf("Swap: "); 183 printf("Swap: ");
162 printf(FIELDS_3, 184 printf("%12s%12s%12s\n",
163 scale(&G, info.totalswap), //total 185 scale(&G, info.totalswap), //total
164 scale(&G, info.totalswap - info.freeswap), //used 186 scale(&G, info.totalswap - info.freeswap), //used
165 scale(&G, info.freeswap) //free 187 scale(&G, info.freeswap) //free