comparison toys/vmstat.c @ 561:c97e338a4126

toybuf usage enhancement, tabs to spaces, teminal height refresh
author Elie De Brauwer <eliedebrauwer@gmail.com>
date Wed, 11 Apr 2012 19:11:45 +0200
parents 120b3dde7cf4
children 4d802d438983
comparison
equal deleted inserted replaced
560:979c5ab6f0c2 561:c97e338a4126
19 count Number of updates to display, the default is inifinite. 19 count Number of updates to display, the default is inifinite.
20 */ 20 */
21 21
22 #include "toys.h" 22 #include "toys.h"
23 23
24 void read_proc_stat(unsigned int * proc_running, unsigned int * proc_blocked, 24 void read_proc_stat(unsigned int * proc_running, unsigned int * proc_blocked,
25 uint64_t * sys_irq, uint64_t * sys_ctxt, 25 uint64_t * sys_irq, uint64_t * sys_ctxt,
26 uint64_t * cpu_user, uint64_t * cpu_sys, uint64_t * cpu_idle, uint64_t * cpu_wait) 26 uint64_t * cpu_user, uint64_t * cpu_sys, uint64_t * cpu_idle, uint64_t * cpu_wait)
27 { 27 {
28 char * off; 28 char * off;
29 uint64_t c_user, c_nice, c_sys, c_irq, c_sirq; 29 uint64_t c_user, c_nice, c_sys, c_irq, c_sirq;
30 int fd = xopen("/proc/stat", O_RDONLY); 30 int fd = xopen("/proc/stat", O_RDONLY);
31 if (fdlength(fd) > sizeof(toybuf)) 31 size_t s = xread(fd, toybuf, sizeof(toybuf)-1);
32 error_exit("/proc/stat is too large"); 32 toybuf[s] = 0;
33 xread(fd, toybuf, sizeof(toybuf)); 33 if ( s == sizeof(toybuf)-1)
34 error_exit("/proc/stat is too large");
34 35
35 off = strstr(toybuf, "cpu "); 36 off = strstr(toybuf, "cpu ");
36 // Ignoring steal and guest fields for now. 37 // Ignoring steal and guest fields for now.
37 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); 38 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);
38 *cpu_user = c_user + c_nice; 39 *cpu_user = c_user + c_nice;
39 *cpu_sys = c_sys + c_irq + c_sirq; 40 *cpu_sys = c_sys + c_irq + c_sirq;
40 off = strstr(toybuf, "intr"); 41 off = strstr(toybuf, "intr");
41 if (off) sscanf(off, "intr %Lu", sys_irq); 42 if (off) sscanf(off, "intr %Lu", sys_irq);
42 43
43 off = strstr(toybuf, "ctxt"); 44 off = strstr(toybuf, "ctxt");
44 if (off) sscanf(off, "ctxt %Lu", sys_ctxt); 45 if (off) sscanf(off, "ctxt %Lu", sys_ctxt);
45 46
46 off = strstr(toybuf, "procs_running"); 47 off = strstr(toybuf, "procs_running");
47 if (off) sscanf(off, "procs_running %u", proc_running); 48 if (off) sscanf(off, "procs_running %u", proc_running);
48 (*proc_running)--; // look, i'm invisible. 49 (*proc_running)--; // look, i'm invisible.
49
50 off = strstr(toybuf, "procs_blocked");
51 if (off) sscanf(off, "procs_blocked %u", proc_blocked);
52 50
53 close(fd); 51 off = strstr(toybuf, "procs_blocked");
52 if (off) sscanf(off, "procs_blocked %u", proc_blocked);
53
54 close(fd);
54 } 55 }
55 56
56 void read_proc_meminfo(unsigned long * mem_swapped, unsigned long * mem_free, 57 void read_proc_meminfo(unsigned long * mem_swapped, unsigned long * mem_free,
57 unsigned long * mem_buff, unsigned long * mem_cache) 58 unsigned long * mem_buff, unsigned long * mem_cache)
58 { 59 {
59 char * off; 60 char * off;
60 unsigned long swap_total, swap_free; 61 unsigned long swap_total, swap_free;
61 int fd = xopen("/proc/meminfo", O_RDONLY); 62 int fd = xopen("/proc/meminfo", O_RDONLY);
62 if (fdlength(fd) > sizeof(toybuf)) 63 size_t s = xread(fd, toybuf, sizeof(toybuf)-1);
63 error_exit("/proc/meminfo is too large"); 64 toybuf[s] = 0;
64 xread(fd, toybuf, sizeof(toybuf)); 65 if ( s == sizeof(toybuf)-1)
66 error_exit("/proc/meminfo is too large");
65 67
66 off = strstr(toybuf, "MemFree"); 68 off = strstr(toybuf, "MemFree");
67 if (off) sscanf(off, "MemFree: %lu kB", mem_free); 69 if (off) sscanf(off, "MemFree: %lu kB", mem_free);
68 70
69 off = strstr(toybuf, "Buffers"); 71 off = strstr(toybuf, "Buffers");
70 if (off) sscanf(off, "Buffers: %lu kB", mem_buff); 72 if (off) sscanf(off, "Buffers: %lu kB", mem_buff);
71 73
72 off = strstr(toybuf, "Cached"); 74 off = strstr(toybuf, "Cached");
73 if (off) sscanf(off, "Cached: %lu kB", mem_cache); 75 if (off) sscanf(off, "Cached: %lu kB", mem_cache);
74 76
75 off = strstr(toybuf, "SwapFree"); 77 off = strstr(toybuf, "SwapFree");
76 if (off) sscanf(off, "SwapFree: %lu kB", &swap_free); 78 if (off) sscanf(off, "SwapFree: %lu kB", &swap_free);
77 79
78 off = strstr(toybuf, "SwapTotal"); 80 off = strstr(toybuf, "SwapTotal");
79 if (off) sscanf(off, "SwapTotal: %lu kB", &swap_total); 81 if (off) sscanf(off, "SwapTotal: %lu kB", &swap_total);
80 *mem_swapped = swap_total - swap_free; 82 *mem_swapped = swap_total - swap_free;
81 83
82 close(fd); 84 close(fd);
83 } 85 }
84 86
85 void read_proc_vmstat(unsigned long * io_pages_in, unsigned long * io_pages_out, unsigned long * swap_bytes_in, unsigned long * swap_bytes_out) 87 void read_proc_vmstat(unsigned long * io_pages_in, unsigned long * io_pages_out,
88 unsigned long * swap_bytes_in, unsigned long * swap_bytes_out)
86 { 89 {
87 char * off; 90 char * off;
88 unsigned long s_pages_in, s_pages_out; 91 unsigned long s_pages_in, s_pages_out;
89 unsigned long pagesize_kb = sysconf(_SC_PAGESIZE) / 1024L; 92 unsigned long pagesize_kb = sysconf(_SC_PAGESIZE) / 1024L;
90 int fd = xopen("/proc/vmstat", O_RDONLY); 93 int fd = xopen("/proc/vmstat", O_RDONLY);
91 if (fdlength(fd) > sizeof(toybuf)) 94 size_t s = xread(fd, toybuf, sizeof(toybuf)-1);
92 error_exit("/proc/vmstat is too large"); 95 toybuf[s] = 0;
93 xread(fd, toybuf, sizeof(toybuf)); 96 if ( s == sizeof(toybuf)-1)
97 error_exit("/proc/vmstat is too large");
94 98
95 off = strstr(toybuf, "pgpgin"); 99 off = strstr(toybuf, "pgpgin");
96 if (off) sscanf(off, "pgpgin %lu", io_pages_in); 100 if (off) sscanf(off, "pgpgin %lu", io_pages_in);
97 101
98 off = strstr(toybuf, "pgpgout"); 102 off = strstr(toybuf, "pgpgout");
99 if (off) sscanf(off, "pgpgout %lu", io_pages_out); 103 if (off) sscanf(off, "pgpgout %lu", io_pages_out);
100 104
101 off = strstr(toybuf, "pswpin"); 105 off = strstr(toybuf, "pswpin");
102 if (off) sscanf(off, "pswpin %lu", &s_pages_in); 106 if (off) sscanf(off, "pswpin %lu", &s_pages_in);
103 *swap_bytes_in = s_pages_in * pagesize_kb; 107 *swap_bytes_in = s_pages_in * pagesize_kb;
104 108
105 off = strstr(toybuf, "pswpout"); 109 off = strstr(toybuf, "pswpout");
106 if (off) sscanf(off, "pswpout %lu", &s_pages_out); 110 if (off) sscanf(off, "pswpout %lu", &s_pages_out);
107 *swap_bytes_out = s_pages_out * pagesize_kb; 111 *swap_bytes_out = s_pages_out * pagesize_kb;
108 112
109 close(fd); 113 close(fd);
110 } 114 }
111 115
112 void vmstat_main(void) 116 void vmstat_main(void)
113 { 117 {
114 const char fmt[] = "%2u %2u %6lu %6lu %6lu %6lu %4u %4u %5u %5u %4u %4u %2u %2u %2u %2u\n"; 118 const char fmt[] = "%2u %2u %6lu %6lu %6lu %6lu %4u %4u %5u %5u %4u %4u %2u %2u %2u %2u\n";
115 unsigned int loop_num = 0, loop_max_num = 0, loop_delay = 0; 119 unsigned int loop_num = 0, loop_max_num = 0, loop_delay = 0;
116 unsigned int running = 0, blocked = 0; 120 unsigned int running = 0, blocked = 0;
117 unsigned long mem_swap = 0, mem_free = 0, mem_buff = 0, mem_cache = 0; 121 unsigned long mem_swap = 0, mem_free = 0, mem_buff = 0, mem_cache = 0;
118 unsigned long io_pages_in[2], io_pages_out[2], swap_bytes_in[2], swap_bytes_out[2]; 122 unsigned long io_pages_in[2], io_pages_out[2], swap_bytes_in[2], swap_bytes_out[2];
119 uint64_t sys_irq[2], sys_ctxt[2], cpu_user[2], cpu_sys[2], cpu_idle[2], cpu_wait[2]; 123 uint64_t sys_irq[2], sys_ctxt[2], cpu_user[2], cpu_sys[2], cpu_idle[2], cpu_wait[2];
120 int first_run = 1; 124 int first_run = 1;
121 int no_header = toys.optflags & 0x1; 125 int no_header = toys.optflags & 0x1;
126 unsigned num_rows = 22;
122 127
123 if (toys.optc >= 1) 128 if (toys.optc >= 1)
124 loop_delay = atoi(toys.optargs[0]); 129 loop_delay = atoi(toys.optargs[0]);
125 if (toys.optc >= 2) 130 if (toys.optc >= 2)
126 loop_max_num = atoi(toys.optargs[1]); 131 loop_max_num = atoi(toys.optargs[1]);
127 132
128 if (loop_max_num < 0 || loop_delay < 0) 133 if (loop_max_num < 0 || loop_delay < 0)
129 error_exit("Invalid arguments"); 134 error_exit("Invalid arguments");
130 135
131 while(1) { 136 while(1) {
132 uint64_t total_jif; 137 uint64_t total_jif;
133 int idx = loop_num%2; 138 int idx = loop_num%2;
134 139
135 if(first_run || (!(loop_num % 22) && !no_header)) { 140 if(first_run || (!(loop_num % num_rows) && !no_header)) {
136 printf("procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----\n"); 141 unsigned rows = 0, cols = 0;
137 printf(" r b swpd free buff cache si so bi bo in cs us sy id wa\n"); 142 terminal_size(&cols, &rows);
138 } 143 num_rows = (rows > 3)? rows - 3 : 22;
144 printf("procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----\n");
145 printf(" r b swpd free buff cache si so bi bo in cs us sy id wa\n");
146 }
139 147
140 read_proc_stat(&running, &blocked, &sys_irq[idx], &sys_ctxt[idx], &cpu_user[idx], 148 read_proc_stat(&running, &blocked, &sys_irq[idx], &sys_ctxt[idx], &cpu_user[idx],
141 &cpu_sys[idx], &cpu_idle[idx], &cpu_wait[idx]); 149 &cpu_sys[idx], &cpu_idle[idx], &cpu_wait[idx]);
142 read_proc_meminfo(&mem_swap, &mem_free, &mem_buff, &mem_cache); 150 read_proc_meminfo(&mem_swap, &mem_free, &mem_buff, &mem_cache);
143 read_proc_vmstat(&io_pages_in[idx], &io_pages_out[idx], &swap_bytes_in[idx], &swap_bytes_out[idx]); 151 read_proc_vmstat(&io_pages_in[idx], &io_pages_out[idx], &swap_bytes_in[idx], &swap_bytes_out[idx]);
144 152
145 if (first_run) { 153 if (first_run) {
146 struct sysinfo inf; 154 struct sysinfo inf;
147 sysinfo(&inf); 155 sysinfo(&inf);
148 first_run = 0; 156 first_run = 0;
149 total_jif = cpu_user[idx] + cpu_idle[idx] + cpu_wait[idx]; 157 total_jif = cpu_user[idx] + cpu_idle[idx] + cpu_wait[idx];
150 printf(fmt, running, blocked, mem_swap, mem_free, mem_buff, mem_cache, 158 printf(fmt, running, blocked, mem_swap, mem_free, mem_buff, mem_cache,
151 (unsigned) (swap_bytes_in[idx]/inf.uptime), 159 (unsigned) (swap_bytes_in[idx]/inf.uptime),
152 (unsigned) (swap_bytes_out[idx]/inf.uptime), 160 (unsigned) (swap_bytes_out[idx]/inf.uptime),
153 (unsigned) (io_pages_in[idx]/inf.uptime), 161 (unsigned) (io_pages_in[idx]/inf.uptime),
154 (unsigned) (io_pages_out[idx]/inf.uptime), 162 (unsigned) (io_pages_out[idx]/inf.uptime),
155 (unsigned) (sys_irq[idx]/inf.uptime), 163 (unsigned) (sys_irq[idx]/inf.uptime),
156 (unsigned) (sys_ctxt[idx]/inf.uptime), 164 (unsigned) (sys_ctxt[idx]/inf.uptime),
157 (unsigned) (100*cpu_user[idx]/total_jif), 165 (unsigned) (100*cpu_user[idx]/total_jif),
158 (unsigned) (100*cpu_sys[idx]/total_jif), 166 (unsigned) (100*cpu_sys[idx]/total_jif),
159 (unsigned) (100*cpu_idle[idx]/total_jif), 167 (unsigned) (100*cpu_idle[idx]/total_jif),
160 (unsigned) (100*cpu_wait[idx]/total_jif)); 168 (unsigned) (100*cpu_wait[idx]/total_jif));
161 }else{ 169 }else{
162 total_jif = cpu_user[idx] - cpu_user[!idx] + cpu_idle[idx] - cpu_idle[!idx] + cpu_wait[idx] - cpu_wait[!idx]; 170 total_jif = cpu_user[idx] - cpu_user[!idx] + cpu_idle[idx] - cpu_idle[!idx] + cpu_wait[idx] - cpu_wait[!idx];
163 printf(fmt, running, blocked, mem_swap, mem_free, mem_buff, mem_cache, 171 printf(fmt, running, blocked, mem_swap, mem_free, mem_buff, mem_cache,
164 (unsigned) ((swap_bytes_in[idx] - swap_bytes_in[!idx])/loop_delay), 172 (unsigned) ((swap_bytes_in[idx] - swap_bytes_in[!idx])/loop_delay),
165 (unsigned) ((swap_bytes_out[idx] - swap_bytes_out[!idx])/loop_delay), 173 (unsigned) ((swap_bytes_out[idx] - swap_bytes_out[!idx])/loop_delay),
166 (unsigned) ((io_pages_in[idx] - io_pages_in[!idx])/loop_delay), 174 (unsigned) ((io_pages_in[idx] - io_pages_in[!idx])/loop_delay),
167 (unsigned) ((io_pages_out[idx] - io_pages_out[!idx])/loop_delay), 175 (unsigned) ((io_pages_out[idx] - io_pages_out[!idx])/loop_delay),
168 (unsigned) ((sys_irq[idx] - sys_irq[!idx])/loop_delay), 176 (unsigned) ((sys_irq[idx] - sys_irq[!idx])/loop_delay),
169 (unsigned) ((sys_ctxt[idx] - sys_ctxt[!idx])/loop_delay), 177 (unsigned) ((sys_ctxt[idx] - sys_ctxt[!idx])/loop_delay),
170 (unsigned) (100*(cpu_user[idx] - cpu_user[!idx])/total_jif), 178 (unsigned) (100*(cpu_user[idx] - cpu_user[!idx])/total_jif),
171 (unsigned) (100*(cpu_sys[idx] - cpu_sys[!idx]) /total_jif), 179 (unsigned) (100*(cpu_sys[idx] - cpu_sys[!idx]) /total_jif),
172 (unsigned) (100*(cpu_idle[idx] - cpu_idle[!idx])/total_jif), 180 (unsigned) (100*(cpu_idle[idx] - cpu_idle[!idx])/total_jif),
173 (unsigned) (100*(cpu_wait[idx] - cpu_wait[!idx])/total_jif)); 181 (unsigned) (100*(cpu_wait[idx] - cpu_wait[!idx])/total_jif));
174 } 182 }
175 183
176 loop_num++; 184 loop_num++;
177 if (loop_delay == 0 || (loop_max_num != 0 && loop_num >= loop_max_num)) 185 if (loop_delay == 0 || (loop_max_num != 0 && loop_num >= loop_max_num))
178 break; 186 break;
179 sleep(loop_delay); 187 sleep(loop_delay);
180 } 188 }
181 } 189 }