diff --git a/free.c b/free.c index c788d79e..bd78f028 100644 --- a/free.c +++ b/free.c @@ -1,46 +1,69 @@ -/* free.c - a /proc implementation of free */ -/* Dec14/92 by Brian Edmonds */ -/* Thanks to Rafal Maszkowski for the Total line */ +// free.c - free(1) +// procps utility to display free memory information +// +// All new, Robert Love 18 Nov 2002 +// Original by Brian Edmonds and Rafal Maszkowski 14 Dec 1992 +// +// This program is licensed under the GNU Library General Public License, v2 +// +// Copyright 2003 Robert Love +// Copyright 2004 Albert Cahalan #include "proc/sysinfo.h" #include "proc/version.h" +//#include +#include +#include #include #include #include #include -#include -#include -#define S(X) ( ((unsigned long long)(X) << 10) >> byteshift) +#define S(X) ( ((unsigned long long)(X) << 10) >> shift) -static int byteshift = 10; -static int total = 0; +const char help_message[] = +"usage: free [-b|-k|-m|-g] [-l] [-o] [-t] [-s delay] [-c count] [-V]\n" +" -b,-k,-m,-g show output in bytes, KB, MB, or GB\n" +" -l show detailed low and high memory statistics\n" +" -o use old format (no -/+buffers/cache line)\n" +" -t display total for RAM + swap\n" +" -s update every [delay] seconds\n" +" -c update [count] times\n" +" -V display version information and exit\n" +; int main(int argc, char *argv[]){ int i; + int count = 0; + int shift = 10; + int pause_length = 0; + int show_high = 0; + int show_total = 0; int old_fmt = 0; - int rtime = 0; /* check startup flags */ - while( (i = getopt(argc, argv, "bkmos:tV") ) != -1 ) + while( (i = getopt(argc, argv, "bkmglotc:s:V") ) != -1 ) switch (i) { - case 'b': byteshift = 0; break; - case 'k': byteshift = 10; break; - case 'm': byteshift = 20; break; + case 'b': shift = 0; break; + case 'k': shift = 10; break; + case 'm': shift = 20; break; + case 'g': shift = 30; break; + case 'l': show_high = 1; break; case 'o': old_fmt = 1; break; - case 's': rtime = 1000000 * atof(optarg); break; - case 't': total = 1; break; + case 't': show_total = 1; break; + case 's': pause_length = 1000000 * atof(optarg); break; + case 'c': count = strtoul(optarg, NULL, 10); break; case 'V': display_version(); exit(0); default: - fprintf(stderr, "usage: %s [-b|-k|-m] [-o] [-s delay] [-t] [-V]\n", argv[0]); - return 1; + fwrite(help_message,1,strlen(help_message),stderr); + return 1; } do { meminfo(); printf(" total used free shared buffers cached\n"); printf( - "%-7s %10Ld %10Ld %10Ld %10Ld %10Ld %10Ld\n", "Mem:", + "%-7s %10Lu %10Lu %10Lu %10Lu %10Lu %10Lu\n", "Mem:", S(kb_main_total), S(kb_main_used), S(kb_main_free), @@ -48,33 +71,52 @@ int main(int argc, char *argv[]){ S(kb_main_buffers), S(kb_main_cached) ); - if(!old_fmt){ + // Print low vs. high information, if the user requested it. + // Note we check if low_total==0: if so, then this kernel does + // not export the low and high stats. Note we still want to + // print the high info, even if it is zero. + if (show_high) { printf( - "-/+ buffers/cache: %10Ld %10Ld\n", - S(kb_main_used-kb_main_buffers-kb_main_cached), - S(kb_main_free+kb_main_buffers+kb_main_cached) + "%-7s %10Lu %10Lu %10Lu\n", "Low:", + S(kb_low_total), + S(kb_low_total - kb_low_free), + S(kb_low_free) + ); + printf( + "%-7s %10Lu %10Lu %10Lu\n", "High:", + S(kb_high_total), + S(kb_high_total - kb_high_free), + S(kb_high_free) + ); + } + if(!old_fmt){ + unsigned KLONG buffers_plus_cached = kb_main_buffers + kb_main_cached; + printf( + "-/+ buffers/cache: %10Lu %10Lu\n", + S(kb_main_used - buffers_plus_cached), + S(kb_main_free + buffers_plus_cached) ); } printf( - "%-7s %10Ld %10Ld %10Ld\n", "Swap:", + "%-7s %10Lu %10Lu %10Lu\n", "Swap:", S(kb_swap_total), S(kb_swap_used), S(kb_swap_free) ); - if(total == 1){ + if(show_total){ printf( - "%-7s %10Ld %10Ld %10Ld\n", "Total:", + "%-7s %10Lu %10Lu %10Lu\n", "Total:", S(kb_main_total + kb_swap_total), S(kb_main_used + kb_swap_used), S(kb_main_free + kb_swap_free) ); } - if(rtime){ + if(pause_length){ fputc('\n', stdout); fflush(stdout); - usleep(rtime); + if (count != 1) usleep(pause_length); } - } while(rtime); + } while(pause_length && --count); return 0; } diff --git a/pmap.c b/pmap.c index 003db4fc..bbf278d8 100644 --- a/pmap.c +++ b/pmap.c @@ -230,7 +230,7 @@ static int one_proc(proc_t *p){ } if(d_option){ printf( - "mapped %ldK writeable/private: %ldK shared: %ldK\n", + "mapped: %ldK writeable/private: %ldK shared: %ldK\n", (total_shared + total_private_writeable + total_private_readonly) >> 10, total_private_writeable >> 10, total_shared >> 10 diff --git a/proc/library.map b/proc/library.map index 4669a786..c9d25100 100644 --- a/proc/library.map +++ b/proc/library.map @@ -14,7 +14,8 @@ global: kb_active; kb_inactive; kb_main_buffers; kb_main_cached; kb_main_free; kb_main_total; kb_main_used; kb_swap_free; kb_swap_total; kb_swap_used; kb_main_shared; - vm_pgpgin; vm_pgpgout; vm_pswpin; vm_pswpout; free_slabinfo; put_slabinfo; - get_slabinfo; get_proc_stats; + kb_low_total; kb_low_free; kb_high_total; kb_high_free; + vm_pgpgin; vm_pgpgout; vm_pswpin; vm_pswpout; + free_slabinfo; put_slabinfo; get_slabinfo; get_proc_stats; local: *; };