Thank you.
One minor thing; in the code that has been commited, the seen_cached
and seen_available vars have been combined into one
(seen_cached_and_available). However the code now parses all lines in
/proc/meminfo twice until both Cached and MemAvailable have been
found:
seen_cached_and_available = 2;
while (fgets(buf, sizeof(buf), fp)) {
if (sscanf(buf, "Cached: %lu %*s\n", cached_kb) == 1)
if (--seen_cached_and_available == 0)
break;
if (sscanf(buf, "MemAvailable: %lu %*s\n", available_kb) == 1)
if (--seen_cached_and_available == 0)
break;
}
However the original code only checks for things it has not seen yet;
for example if it finds "Cached" then it will only check for
MemAvailable in the remaining lines:
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;
}
}
I think it would be convenient to revert this change and keep the two
separate variables in order to avoid doing unnecessary work.
Best,
Guillermo
El mar., 30 oct. 2018 a las 14:15, Denys Vlasenko
(<[email protected]>) escribió:
>
> Applied, thanks
> On Thu, Oct 4, 2018 at 4:27 PM Guillermo Rodríguez
> <[email protected]> wrote:
> >
> > 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
--
Guillermo Rodriguez Garcia
[email protected]
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox