Show estimated available memory if this is provided by the
kernel. See [1] for the full story.

 [1]: 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773

Signed-off-by: Guillermo Rodriguez <[email protected]>
---
 procps/free.c | 54 ++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 34 insertions(+), 20 deletions(-)

diff --git a/procps/free.c b/procps/free.c
index 0991713..e7ba974 100644
--- a/procps/free.c
+++ b/procps/free.c
@@ -44,27 +44,36 @@ static unsigned long long scale(unsigned long d)
        return ((unsigned long long)d * G.mem_unit) >> G_unit_steps;
 }
 
-static unsigned long parse_cached_kb(void)
+static unsigned int parse_meminfo(unsigned long *cached_kb, unsigned long 
*available_kb)
 {
        char buf[60]; /* actual lines we expect are ~30 chars or less */
        FILE *f;
-       unsigned long cached = 0;
+       int seen_cached = 0;
+       int seen_available = 0;
+
+       *cached_kb = *available_kb = 0;
 
        f = xfopen_for_read("/proc/meminfo");
-       while (fgets(buf, sizeof(buf), f) != NULL) {
-               if (sscanf(buf, "Cached: %lu %*s\n", &cached) == 1)
-                       break;
+       while (fgets(buf, sizeof(buf), f) != NULL && !(seen_cached && 
seen_available)) {
+               if (!seen_cached && sscanf(buf, "Cached: %lu %*s\n", cached_kb) 
== 1) {
+                       seen_cached = 1;
+               }
+               else if (!seen_available && sscanf(buf, "MemAvailable: %lu 
%*s\n", available_kb) == 1) {
+                       seen_available = 1;
+               }
        }
        fclose(f);
 
-       return cached;
+       return seen_available;
 }
 
 int free_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int free_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM))
 {
        struct sysinfo info;
-       unsigned long long cached;
+       unsigned long long cached, available;
+       unsigned long cached_kb, available_kb;
+       int seen_available;
 
        INIT_G();
 
@@ -95,17 +104,19 @@ int free_main(int argc UNUSED_PARAM, char **argv 
IF_NOT_DESKTOP(UNUSED_PARAM))
        /* Kernels prior to 2.4.x will return info.mem_unit==0, so cope... */
        G.mem_unit = (info.mem_unit ? info.mem_unit : 1);
 
-       /* Extract cached from /proc/meminfo and convert to mem_units */
-       cached = ((unsigned long long) parse_cached_kb() * 1024) / G.mem_unit;
+       /* Extract cached and memavailable from /proc/meminfo and convert to 
mem_units */
+       seen_available = parse_meminfo(&cached_kb, &available_kb);
+       cached = ((unsigned long long) cached_kb * 1024) / G.mem_unit;
+       available = ((unsigned long long) available_kb * 1024) / G.mem_unit;
 
-       printf("       %11s%11s%11s%11s%11s%11s\n",
+       printf("       %12s%12s%12s%12s%12s%12s\n",
                "total",
                "used",
                "free",
-               "shared", "buffers", "cached" /* swap and total don't have 
these columns */
+               "shared", "buff/cache", "available" /* swap and total don't 
have these columns */
        );
 
-#define FIELDS_6 "%11llu%11llu%11llu%11llu%11llu%11llu\n"
+#define FIELDS_6 "%12llu%12llu%12llu%12llu%12llu%12llu\n"
 #define FIELDS_3 (FIELDS_6 + 3*6)
 #define FIELDS_2 (FIELDS_6 + 4*6)
 
@@ -115,16 +126,19 @@ int free_main(int argc UNUSED_PARAM, char **argv 
IF_NOT_DESKTOP(UNUSED_PARAM))
                scale(info.totalram - info.freeram),
                scale(info.freeram),
                scale(info.sharedram),
-               scale(info.bufferram),
-               scale(cached)
+               scale(info.bufferram) + scale(cached),
+               scale(available)
        );
-       /* Show alternate, more meaningful busy/free numbers by counting
+       /* On kernels < 3.14, MemAvailable is not provided.
+        * Show alternate, more meaningful busy/free numbers by counting
         * buffer cache as free memory. */
-       printf("-/+ buffers/cache:");
-       printf(FIELDS_2,
-               scale(info.totalram - info.freeram - info.bufferram - cached),
-               scale(info.freeram + info.bufferram + cached)
-       );
+       if (!seen_available) {
+               printf("-/+ buffers/cache:");
+               printf(FIELDS_2,
+                       scale(info.totalram - info.freeram - info.bufferram - 
cached),
+                       scale(info.freeram + info.bufferram + cached)
+               );
+       }
 #if BB_MMU
        printf("Swap:  ");
        printf(FIELDS_3,
-- 
1.9.1

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to