aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toys/vmstat.c290
1 files changed, 149 insertions, 141 deletions
diff --git a/toys/vmstat.c b/toys/vmstat.c
index 12669458..e186961d 100644
--- a/toys/vmstat.c
+++ b/toys/vmstat.c
@@ -21,161 +21,169 @@ config VMSTAT
#include "toys.h"
-void read_proc_stat(unsigned int * proc_running, unsigned int * proc_blocked,
- uint64_t * sys_irq, uint64_t * sys_ctxt,
- uint64_t * cpu_user, uint64_t * cpu_sys, uint64_t * cpu_idle, uint64_t * cpu_wait)
+void read_proc_stat(unsigned int * proc_running, unsigned int * proc_blocked,
+ uint64_t * sys_irq, uint64_t * sys_ctxt,
+ uint64_t * cpu_user, uint64_t * cpu_sys, uint64_t * cpu_idle, uint64_t * cpu_wait)
{
- char * off;
- uint64_t c_user, c_nice, c_sys, c_irq, c_sirq;
- int fd = xopen("/proc/stat", O_RDONLY);
- if (fdlength(fd) > sizeof(toybuf))
- error_exit("/proc/stat is too large");
- xread(fd, toybuf, sizeof(toybuf));
-
- off = strstr(toybuf, "cpu ");
- // Ignoring steal and guest fields for now.
- if (off) sscanf(off, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", &c_user, &c_nice, &c_sys, cpu_idle, cpu_wait, &c_irq, &c_sirq);
- *cpu_user = c_user + c_nice;
- *cpu_sys = c_sys + c_irq + c_sirq;
- off = strstr(toybuf, "intr");
- if (off) sscanf(off, "intr %Lu", sys_irq);
-
- off = strstr(toybuf, "ctxt");
- if (off) sscanf(off, "ctxt %Lu", sys_ctxt);
-
- off = strstr(toybuf, "procs_running");
- if (off) sscanf(off, "procs_running %u", proc_running);
- (*proc_running)--; // look, i'm invisible.
-
- off = strstr(toybuf, "procs_blocked");
- if (off) sscanf(off, "procs_blocked %u", proc_blocked);
-
- close(fd);
+ char * off;
+ uint64_t c_user, c_nice, c_sys, c_irq, c_sirq;
+ int fd = xopen("/proc/stat", O_RDONLY);
+ size_t s = xread(fd, toybuf, sizeof(toybuf)-1);
+ toybuf[s] = 0;
+ if ( s == sizeof(toybuf)-1)
+ error_exit("/proc/stat is too large");
+
+ off = strstr(toybuf, "cpu ");
+ // Ignoring steal and guest fields for now.
+ if (off) sscanf(off, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", &c_user, &c_nice, &c_sys, cpu_idle, cpu_wait, &c_irq, &c_sirq);
+ *cpu_user = c_user + c_nice;
+ *cpu_sys = c_sys + c_irq + c_sirq;
+ off = strstr(toybuf, "intr");
+ if (off) sscanf(off, "intr %Lu", sys_irq);
+
+ off = strstr(toybuf, "ctxt");
+ if (off) sscanf(off, "ctxt %Lu", sys_ctxt);
+
+ off = strstr(toybuf, "procs_running");
+ if (off) sscanf(off, "procs_running %u", proc_running);
+ (*proc_running)--; // look, i'm invisible.
+
+ off = strstr(toybuf, "procs_blocked");
+ if (off) sscanf(off, "procs_blocked %u", proc_blocked);
+
+ close(fd);
}
-void read_proc_meminfo(unsigned long * mem_swapped, unsigned long * mem_free,
- unsigned long * mem_buff, unsigned long * mem_cache)
+void read_proc_meminfo(unsigned long * mem_swapped, unsigned long * mem_free,
+ unsigned long * mem_buff, unsigned long * mem_cache)
{
- char * off;
- unsigned long swap_total, swap_free;
- int fd = xopen("/proc/meminfo", O_RDONLY);
- if (fdlength(fd) > sizeof(toybuf))
- error_exit("/proc/meminfo is too large");
- xread(fd, toybuf, sizeof(toybuf));
+ char * off;
+ unsigned long swap_total, swap_free;
+ int fd = xopen("/proc/meminfo", O_RDONLY);
+ size_t s = xread(fd, toybuf, sizeof(toybuf)-1);
+ toybuf[s] = 0;
+ if ( s == sizeof(toybuf)-1)
+ error_exit("/proc/meminfo is too large");
- off = strstr(toybuf, "MemFree");
- if (off) sscanf(off, "MemFree: %lu kB", mem_free);
+ off = strstr(toybuf, "MemFree");
+ if (off) sscanf(off, "MemFree: %lu kB", mem_free);
- off = strstr(toybuf, "Buffers");
- if (off) sscanf(off, "Buffers: %lu kB", mem_buff);
+ off = strstr(toybuf, "Buffers");
+ if (off) sscanf(off, "Buffers: %lu kB", mem_buff);
- off = strstr(toybuf, "Cached");
- if (off) sscanf(off, "Cached: %lu kB", mem_cache);
+ off = strstr(toybuf, "Cached");
+ if (off) sscanf(off, "Cached: %lu kB", mem_cache);
- off = strstr(toybuf, "SwapFree");
- if (off) sscanf(off, "SwapFree: %lu kB", &swap_free);
+ off = strstr(toybuf, "SwapFree");
+ if (off) sscanf(off, "SwapFree: %lu kB", &swap_free);
- off = strstr(toybuf, "SwapTotal");
- if (off) sscanf(off, "SwapTotal: %lu kB", &swap_total);
- *mem_swapped = swap_total - swap_free;
+ off = strstr(toybuf, "SwapTotal");
+ if (off) sscanf(off, "SwapTotal: %lu kB", &swap_total);
+ *mem_swapped = swap_total - swap_free;
- close(fd);
+ close(fd);
}
-void read_proc_vmstat(unsigned long * io_pages_in, unsigned long * io_pages_out, unsigned long * swap_bytes_in, unsigned long * swap_bytes_out)
+void read_proc_vmstat(unsigned long * io_pages_in, unsigned long * io_pages_out,
+ unsigned long * swap_bytes_in, unsigned long * swap_bytes_out)
{
- char * off;
- unsigned long s_pages_in, s_pages_out;
- unsigned long pagesize_kb = sysconf(_SC_PAGESIZE) / 1024L;
- int fd = xopen("/proc/vmstat", O_RDONLY);
- if (fdlength(fd) > sizeof(toybuf))
- error_exit("/proc/vmstat is too large");
- xread(fd, toybuf, sizeof(toybuf));
-
- off = strstr(toybuf, "pgpgin");
- if (off) sscanf(off, "pgpgin %lu", io_pages_in);
-
- off = strstr(toybuf, "pgpgout");
- if (off) sscanf(off, "pgpgout %lu", io_pages_out);
-
- off = strstr(toybuf, "pswpin");
- if (off) sscanf(off, "pswpin %lu", &s_pages_in);
- *swap_bytes_in = s_pages_in * pagesize_kb;
-
- off = strstr(toybuf, "pswpout");
- if (off) sscanf(off, "pswpout %lu", &s_pages_out);
- *swap_bytes_out = s_pages_out * pagesize_kb;
-
- close(fd);
+ char * off;
+ unsigned long s_pages_in, s_pages_out;
+ unsigned long pagesize_kb = sysconf(_SC_PAGESIZE) / 1024L;
+ int fd = xopen("/proc/vmstat", O_RDONLY);
+ size_t s = xread(fd, toybuf, sizeof(toybuf)-1);
+ toybuf[s] = 0;
+ if ( s == sizeof(toybuf)-1)
+ error_exit("/proc/vmstat is too large");
+
+ off = strstr(toybuf, "pgpgin");
+ if (off) sscanf(off, "pgpgin %lu", io_pages_in);
+
+ off = strstr(toybuf, "pgpgout");
+ if (off) sscanf(off, "pgpgout %lu", io_pages_out);
+
+ off = strstr(toybuf, "pswpin");
+ if (off) sscanf(off, "pswpin %lu", &s_pages_in);
+ *swap_bytes_in = s_pages_in * pagesize_kb;
+
+ off = strstr(toybuf, "pswpout");
+ if (off) sscanf(off, "pswpout %lu", &s_pages_out);
+ *swap_bytes_out = s_pages_out * pagesize_kb;
+
+ close(fd);
}
void vmstat_main(void)
-{
- const char fmt[] = "%2u %2u %6lu %6lu %6lu %6lu %4u %4u %5u %5u %4u %4u %2u %2u %2u %2u\n";
- unsigned int loop_num = 0, loop_max_num = 0, loop_delay = 0;
- unsigned int running = 0, blocked = 0;
- unsigned long mem_swap = 0, mem_free = 0, mem_buff = 0, mem_cache = 0;
- unsigned long io_pages_in[2], io_pages_out[2], swap_bytes_in[2], swap_bytes_out[2];
- uint64_t sys_irq[2], sys_ctxt[2], cpu_user[2], cpu_sys[2], cpu_idle[2], cpu_wait[2];
- int first_run = 1;
- int no_header = toys.optflags & 0x1;
-
- if (toys.optc >= 1)
- loop_delay = atoi(toys.optargs[0]);
- if (toys.optc >= 2)
- loop_max_num = atoi(toys.optargs[1]);
-
- if (loop_max_num < 0 || loop_delay < 0)
- error_exit("Invalid arguments");
-
- while(1) {
- uint64_t total_jif;
- int idx = loop_num%2;
-
- if(first_run || (!(loop_num % 22) && !no_header)) {
- printf("procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----\n");
- printf(" r b swpd free buff cache si so bi bo in cs us sy id wa\n");
- }
-
- read_proc_stat(&running, &blocked, &sys_irq[idx], &sys_ctxt[idx], &cpu_user[idx],
- &cpu_sys[idx], &cpu_idle[idx], &cpu_wait[idx]);
- read_proc_meminfo(&mem_swap, &mem_free, &mem_buff, &mem_cache);
- read_proc_vmstat(&io_pages_in[idx], &io_pages_out[idx], &swap_bytes_in[idx], &swap_bytes_out[idx]);
-
- if (first_run) {
- struct sysinfo inf;
- sysinfo(&inf);
- first_run = 0;
- total_jif = cpu_user[idx] + cpu_idle[idx] + cpu_wait[idx];
- printf(fmt, running, blocked, mem_swap, mem_free, mem_buff, mem_cache,
- (unsigned) (swap_bytes_in[idx]/inf.uptime),
- (unsigned) (swap_bytes_out[idx]/inf.uptime),
- (unsigned) (io_pages_in[idx]/inf.uptime),
- (unsigned) (io_pages_out[idx]/inf.uptime),
- (unsigned) (sys_irq[idx]/inf.uptime),
- (unsigned) (sys_ctxt[idx]/inf.uptime),
- (unsigned) (100*cpu_user[idx]/total_jif),
- (unsigned) (100*cpu_sys[idx]/total_jif),
- (unsigned) (100*cpu_idle[idx]/total_jif),
- (unsigned) (100*cpu_wait[idx]/total_jif));
- }else{
- total_jif = cpu_user[idx] - cpu_user[!idx] + cpu_idle[idx] - cpu_idle[!idx] + cpu_wait[idx] - cpu_wait[!idx];
- printf(fmt, running, blocked, mem_swap, mem_free, mem_buff, mem_cache,
- (unsigned) ((swap_bytes_in[idx] - swap_bytes_in[!idx])/loop_delay),
- (unsigned) ((swap_bytes_out[idx] - swap_bytes_out[!idx])/loop_delay),
- (unsigned) ((io_pages_in[idx] - io_pages_in[!idx])/loop_delay),
- (unsigned) ((io_pages_out[idx] - io_pages_out[!idx])/loop_delay),
- (unsigned) ((sys_irq[idx] - sys_irq[!idx])/loop_delay),
- (unsigned) ((sys_ctxt[idx] - sys_ctxt[!idx])/loop_delay),
- (unsigned) (100*(cpu_user[idx] - cpu_user[!idx])/total_jif),
- (unsigned) (100*(cpu_sys[idx] - cpu_sys[!idx]) /total_jif),
- (unsigned) (100*(cpu_idle[idx] - cpu_idle[!idx])/total_jif),
- (unsigned) (100*(cpu_wait[idx] - cpu_wait[!idx])/total_jif));
- }
-
- loop_num++;
- if (loop_delay == 0 || (loop_max_num != 0 && loop_num >= loop_max_num))
- break;
- sleep(loop_delay);
- }
+{
+ const char fmt[] = "%2u %2u %6lu %6lu %6lu %6lu %4u %4u %5u %5u %4u %4u %2u %2u %2u %2u\n";
+ unsigned int loop_num = 0, loop_max_num = 0, loop_delay = 0;
+ unsigned int running = 0, blocked = 0;
+ unsigned long mem_swap = 0, mem_free = 0, mem_buff = 0, mem_cache = 0;
+ unsigned long io_pages_in[2], io_pages_out[2], swap_bytes_in[2], swap_bytes_out[2];
+ uint64_t sys_irq[2], sys_ctxt[2], cpu_user[2], cpu_sys[2], cpu_idle[2], cpu_wait[2];
+ int first_run = 1;
+ int no_header = toys.optflags & 0x1;
+ unsigned num_rows = 22;
+
+ if (toys.optc >= 1)
+ loop_delay = atoi(toys.optargs[0]);
+ if (toys.optc >= 2)
+ loop_max_num = atoi(toys.optargs[1]);
+
+ if (loop_max_num < 0 || loop_delay < 0)
+ error_exit("Invalid arguments");
+
+ while(1) {
+ uint64_t total_jif;
+ int idx = loop_num%2;
+
+ if(first_run || (!(loop_num % num_rows) && !no_header)) {
+ unsigned rows = 0, cols = 0;
+ terminal_size(&cols, &rows);
+ num_rows = (rows > 3)? rows - 3 : 22;
+ printf("procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----\n");
+ printf(" r b swpd free buff cache si so bi bo in cs us sy id wa\n");
+ }
+
+ read_proc_stat(&running, &blocked, &sys_irq[idx], &sys_ctxt[idx], &cpu_user[idx],
+ &cpu_sys[idx], &cpu_idle[idx], &cpu_wait[idx]);
+ read_proc_meminfo(&mem_swap, &mem_free, &mem_buff, &mem_cache);
+ read_proc_vmstat(&io_pages_in[idx], &io_pages_out[idx], &swap_bytes_in[idx], &swap_bytes_out[idx]);
+
+ if (first_run) {
+ struct sysinfo inf;
+ sysinfo(&inf);
+ first_run = 0;
+ total_jif = cpu_user[idx] + cpu_idle[idx] + cpu_wait[idx];
+ printf(fmt, running, blocked, mem_swap, mem_free, mem_buff, mem_cache,
+ (unsigned) (swap_bytes_in[idx]/inf.uptime),
+ (unsigned) (swap_bytes_out[idx]/inf.uptime),
+ (unsigned) (io_pages_in[idx]/inf.uptime),
+ (unsigned) (io_pages_out[idx]/inf.uptime),
+ (unsigned) (sys_irq[idx]/inf.uptime),
+ (unsigned) (sys_ctxt[idx]/inf.uptime),
+ (unsigned) (100*cpu_user[idx]/total_jif),
+ (unsigned) (100*cpu_sys[idx]/total_jif),
+ (unsigned) (100*cpu_idle[idx]/total_jif),
+ (unsigned) (100*cpu_wait[idx]/total_jif));
+ }else{
+ total_jif = cpu_user[idx] - cpu_user[!idx] + cpu_idle[idx] - cpu_idle[!idx] + cpu_wait[idx] - cpu_wait[!idx];
+ printf(fmt, running, blocked, mem_swap, mem_free, mem_buff, mem_cache,
+ (unsigned) ((swap_bytes_in[idx] - swap_bytes_in[!idx])/loop_delay),
+ (unsigned) ((swap_bytes_out[idx] - swap_bytes_out[!idx])/loop_delay),
+ (unsigned) ((io_pages_in[idx] - io_pages_in[!idx])/loop_delay),
+ (unsigned) ((io_pages_out[idx] - io_pages_out[!idx])/loop_delay),
+ (unsigned) ((sys_irq[idx] - sys_irq[!idx])/loop_delay),
+ (unsigned) ((sys_ctxt[idx] - sys_ctxt[!idx])/loop_delay),
+ (unsigned) (100*(cpu_user[idx] - cpu_user[!idx])/total_jif),
+ (unsigned) (100*(cpu_sys[idx] - cpu_sys[!idx]) /total_jif),
+ (unsigned) (100*(cpu_idle[idx] - cpu_idle[!idx])/total_jif),
+ (unsigned) (100*(cpu_wait[idx] - cpu_wait[!idx])/total_jif));
+ }
+
+ loop_num++;
+ if (loop_delay == 0 || (loop_max_num != 0 && loop_num >= loop_max_num))
+ break;
+ sleep(loop_delay);
+ }
}