diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-18 12:08:02 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-18 12:08:02 +0200 |
commit | dc30f3dce27bdcccb8450a2418061b4bcdc0ea14 (patch) | |
tree | 31840c006d598c7fee08796f2ba19c09d85df083 | |
parent | 2c436679fbb5fa38b0e7a505022a2075fab87d84 (diff) | |
download | busybox-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.h | 4 | ||||
-rw-r--r-- | procps/free.c | 80 |
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)? | ||
1072 | const char *make_human_readable_str(unsigned long long size, | 1072 | const 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 @@ | |||
38 | struct globals { | 59 | struct 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 | ||
50 | static unsigned long long scale(struct globals *g, unsigned long d) | 71 | static 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 |