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 |
