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>
This commit is contained in:
parent
2c436679fb
commit
dc30f3dce2
@ -1065,10 +1065,10 @@ char *smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) FAST_
|
|||||||
/* If block_size == 0, display size without fractional part,
|
/* If block_size == 0, display size without fractional part,
|
||||||
* else display (size * block_size) with one decimal digit.
|
* else display (size * block_size) with one decimal digit.
|
||||||
* If display_unit == 0, show value no bigger than 1024 with suffix (K,M,G...),
|
* 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. */
|
* else divide by display_unit and do not use suffix.
|
||||||
|
* Returns "auto pointer" */
|
||||||
#define HUMAN_READABLE_MAX_WIDTH 7 /* "1024.0G" */
|
#define HUMAN_READABLE_MAX_WIDTH 7 /* "1024.0G" */
|
||||||
#define HUMAN_READABLE_MAX_WIDTH_STR "7"
|
#define HUMAN_READABLE_MAX_WIDTH_STR "7"
|
||||||
//TODO: provide pointer to buf (avoid statics)?
|
|
||||||
const char *make_human_readable_str(unsigned long long size,
|
const char *make_human_readable_str(unsigned long long size,
|
||||||
unsigned long block_size, unsigned long display_unit) FAST_FUNC;
|
unsigned long block_size, unsigned long display_unit) FAST_FUNC;
|
||||||
/* Put a string of hex bytes ("1b2e66fe"...), return advanced pointer */
|
/* Put a string of hex bytes ("1b2e66fe"...), return advanced pointer */
|
||||||
|
@ -19,9 +19,9 @@
|
|||||||
//kbuild:lib-$(CONFIG_FREE) += free.o
|
//kbuild:lib-$(CONFIG_FREE) += free.o
|
||||||
|
|
||||||
//usage:#define free_trivial_usage
|
//usage:#define free_trivial_usage
|
||||||
//usage: "" IF_DESKTOP("[-bkmg]")
|
//usage: "" IF_DESKTOP("[-bkmgh]")
|
||||||
//usage:#define free_full_usage "\n\n"
|
//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:
|
||||||
//usage:#define free_example_usage
|
//usage:#define free_example_usage
|
||||||
//usage: "$ free\n"
|
//usage: "$ free\n"
|
||||||
@ -29,6 +29,27 @@
|
|||||||
//usage: " Mem: 257628 248724 8904 59644 93124\n"
|
//usage: " Mem: 257628 248724 8904 59644 93124\n"
|
||||||
//usage: " Swap: 128516 8404 120112\n"
|
//usage: " Swap: 128516 8404 120112\n"
|
||||||
//usage: "Total: 386144 257128 129016\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"
|
#include "libbb.h"
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
@ -38,18 +59,22 @@
|
|||||||
struct globals {
|
struct globals {
|
||||||
unsigned mem_unit;
|
unsigned mem_unit;
|
||||||
#if ENABLE_DESKTOP
|
#if ENABLE_DESKTOP
|
||||||
uint8_t unit_steps;
|
unsigned unit;
|
||||||
# define G_unit_steps g->unit_steps
|
# define G_unit g->unit
|
||||||
#else
|
#else
|
||||||
# define G_unit_steps 10
|
# define G_unit (1 << 10)
|
||||||
#endif
|
#endif
|
||||||
unsigned long cached_kb, available_kb, reclaimable_kb;
|
unsigned long cached_kb, available_kb, reclaimable_kb;
|
||||||
};
|
};
|
||||||
/* Because of NOFORK, "globals" are not in global data */
|
/* 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) */
|
/* 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))
|
|||||||
int seen_available;
|
int seen_available;
|
||||||
|
|
||||||
#if ENABLE_DESKTOP
|
#if ENABLE_DESKTOP
|
||||||
G.unit_steps = 10;
|
G.unit = 1 << 10;
|
||||||
if (argv[1] && argv[1][0] == '-') {
|
if (argv[1] && argv[1][0] == '-') {
|
||||||
switch (argv[1][1]) {
|
switch (argv[1][1]) {
|
||||||
case 'b':
|
case 'b':
|
||||||
G.unit_steps = 0;
|
G.unit = 1;
|
||||||
break;
|
break;
|
||||||
case 'k': /* 2^10 */
|
case 'k': /* 2^10 */
|
||||||
/* G.unit_steps = 10; - already is */
|
/* G.unit = 1 << 10; - already is */
|
||||||
break;
|
break;
|
||||||
case 'm': /* 2^20 */
|
case 'm': /* 2^20 */
|
||||||
G.unit_steps = 20;
|
G.unit = 1 << 20;
|
||||||
break;
|
break;
|
||||||
case 'g': /* 2^30 */
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
@ -126,23 +158,13 @@ int free_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM))
|
|||||||
cached += ((unsigned long long) G.reclaimable_kb * 1024) / G.mem_unit;
|
cached += ((unsigned long long) G.reclaimable_kb * 1024) / G.mem_unit;
|
||||||
cached_plus_free = cached + info.freeram;
|
cached_plus_free = cached + info.freeram;
|
||||||
|
|
||||||
/* In case (long long * G.mem_unit) can overflow, this can be used to reduce the chances */
|
printf("%12s%12s%12s",
|
||||||
#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,
|
|
||||||
scale(&G, info.totalram), //total
|
scale(&G, info.totalram), //total
|
||||||
scale(&G, info.totalram - cached_plus_free), //used
|
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, info.sharedram), //shared
|
||||||
scale(&G, cached), //buff/cache
|
scale(&G, cached), //buff/cache
|
||||||
scale(&G, available) //available
|
scale(&G, available) //available
|
||||||
@ -152,14 +174,14 @@ int free_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM))
|
|||||||
* buffer cache as free memory. */
|
* buffer cache as free memory. */
|
||||||
if (!seen_available) {
|
if (!seen_available) {
|
||||||
printf("-/+ buffers/cache: ");
|
printf("-/+ buffers/cache: ");
|
||||||
printf(FIELDS_2,
|
printf("%12s%12s%12s\n" + 4,
|
||||||
scale(&G, info.totalram - cached_plus_free), //used
|
scale(&G, info.totalram - cached_plus_free), //used
|
||||||
scale(&G, cached_plus_free) //free
|
scale(&G, cached_plus_free) //free
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#if BB_MMU
|
#if BB_MMU
|
||||||
printf("Swap: ");
|
printf("Swap: ");
|
||||||
printf(FIELDS_3,
|
printf("%12s%12s%12s\n",
|
||||||
scale(&G, info.totalswap), //total
|
scale(&G, info.totalswap), //total
|
||||||
scale(&G, info.totalswap - info.freeswap), //used
|
scale(&G, info.totalswap - info.freeswap), //used
|
||||||
scale(&G, info.freeswap) //free
|
scale(&G, info.freeswap) //free
|
||||||
|
Loading…
Reference in New Issue
Block a user