diff options
author | Maksym Kryzhanovskyy <xmaks@email.cz> | 2011-06-05 03:37:14 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-06-05 03:37:14 +0200 |
commit | 9f7780250ce4bbee9c0a8f1044875e303479e196 (patch) | |
tree | 88d314931dbe8f7a4c89821bfbb3aefc40220670 | |
parent | 5d3aaceb790461dca3f770483bbccd161e78a728 (diff) | |
download | busybox-w32-9f7780250ce4bbee9c0a8f1044875e303479e196.tar.gz busybox-w32-9f7780250ce4bbee9c0a8f1044875e303479e196.tar.bz2 busybox-w32-9f7780250ce4bbee9c0a8f1044875e303479e196.zip |
iostat: code shrink
function old new delta
iostat_main 2048 2400 +352
is_partition 48 - -48
print_stats_dev_struct 350 - -350
Signed-off-by: Maksym Kryzhanovskyy <xmaks@email.cz>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | procps/iostat.c | 237 |
1 files changed, 117 insertions, 120 deletions
diff --git a/procps/iostat.c b/procps/iostat.c index cd233c72f..51c5fac08 100644 --- a/procps/iostat.c +++ b/procps/iostat.c | |||
@@ -7,23 +7,24 @@ | |||
7 | * Licensed under GPLv2, see file LICENSE in this source tree. | 7 | * Licensed under GPLv2, see file LICENSE in this source tree. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | //applet:IF_IOSTAT(APPLET(iostat, BB_DIR_BIN, BB_SUID_DROP)) | ||
11 | |||
12 | //kbuild:lib-$(CONFIG_IOSTAT) += iostat.o | ||
13 | |||
14 | //config:config IOSTAT | 10 | //config:config IOSTAT |
15 | //config: bool "iostat" | 11 | //config: bool "iostat" |
16 | //config: default y | 12 | //config: default y |
17 | //config: help | 13 | //config: help |
18 | //config: Report CPU and I/O statistics | 14 | //config: Report CPU and I/O statistics |
19 | 15 | ||
16 | //applet:IF_IOSTAT(APPLET(iostat, BB_DIR_BIN, BB_SUID_DROP)) | ||
17 | |||
18 | //kbuild:lib-$(CONFIG_IOSTAT) += iostat.o | ||
19 | |||
20 | #include "libbb.h" | 20 | #include "libbb.h" |
21 | #include <sys/utsname.h> /* Need struct utsname */ | 21 | #include <sys/utsname.h> /* struct utsname */ |
22 | 22 | ||
23 | //#define debug(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__) | 23 | //#define debug(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__) |
24 | #define debug(fmt, ...) ((void)0) | 24 | #define debug(fmt, ...) ((void)0) |
25 | 25 | ||
26 | #define MAX_DEVICE_NAME 12 | 26 | #define MAX_DEVICE_NAME 12 |
27 | #define MAX_DEVICE_NAME_STR "12" | ||
27 | 28 | ||
28 | #if 1 | 29 | #if 1 |
29 | typedef unsigned long long cputime_t; | 30 | typedef unsigned long long cputime_t; |
@@ -64,21 +65,27 @@ typedef struct { | |||
64 | cputime_t itv; | 65 | cputime_t itv; |
65 | } stats_cpu_pair_t; | 66 | } stats_cpu_pair_t; |
66 | 67 | ||
67 | struct stats_dev { | 68 | typedef struct { |
68 | char dname[MAX_DEVICE_NAME]; | ||
69 | unsigned long long rd_sectors; | 69 | unsigned long long rd_sectors; |
70 | unsigned long long wr_sectors; | 70 | unsigned long long wr_sectors; |
71 | unsigned long rd_ops; | 71 | unsigned long rd_ops; |
72 | unsigned long wr_ops; | 72 | unsigned long wr_ops; |
73 | }; | 73 | } stats_dev_data_t; |
74 | |||
75 | typedef struct stats_dev { | ||
76 | struct stats_dev *next; | ||
77 | char dname[MAX_DEVICE_NAME + 1]; | ||
78 | stats_dev_data_t prev_data; | ||
79 | stats_dev_data_t curr_data; | ||
80 | } stats_dev_t; | ||
74 | 81 | ||
75 | /* Globals. Sort by size and access frequency. */ | 82 | /* Globals. Sort by size and access frequency. */ |
76 | struct globals { | 83 | struct globals { |
77 | smallint show_all; | 84 | smallint show_all; |
78 | unsigned total_cpus; /* Number of CPUs */ | 85 | unsigned total_cpus; /* Number of CPUs */ |
79 | unsigned clk_tck; /* Number of clock ticks per second */ | 86 | unsigned clk_tck; /* Number of clock ticks per second */ |
80 | llist_t *dev_list; /* List of devices entered on the command line */ | 87 | llist_t *dev_name_list; /* List of devices entered on the command line */ |
81 | struct stats_dev *saved_stats_dev; | 88 | stats_dev_t *stats_dev_list; |
82 | struct tm tmtime; | 89 | struct tm tmtime; |
83 | struct { | 90 | struct { |
84 | const char *str; | 91 | const char *str; |
@@ -114,7 +121,7 @@ static ALWAYS_INLINE int this_is_smp(void) | |||
114 | 121 | ||
115 | static void print_header(void) | 122 | static void print_header(void) |
116 | { | 123 | { |
117 | char buf[16]; | 124 | char buf[32]; |
118 | struct utsname uts; | 125 | struct utsname uts; |
119 | 126 | ||
120 | uname(&uts); /* never fails */ | 127 | uname(&uts); /* never fails */ |
@@ -136,7 +143,7 @@ static void get_localtime(struct tm *ptm) | |||
136 | 143 | ||
137 | static void print_timestamp(void) | 144 | static void print_timestamp(void) |
138 | { | 145 | { |
139 | char buf[20]; | 146 | char buf[64]; |
140 | /* %x: date representation for the current locale */ | 147 | /* %x: date representation for the current locale */ |
141 | /* %X: time representation for the current locale */ | 148 | /* %X: time representation for the current locale */ |
142 | strftime(buf, sizeof(buf), "%x %X", &G.tmtime); | 149 | strftime(buf, sizeof(buf), "%x %X", &G.tmtime); |
@@ -162,18 +169,22 @@ static cputime_t get_smp_uptime(void) | |||
162 | static void get_cpu_statistics(stats_cpu_t *sc) | 169 | static void get_cpu_statistics(stats_cpu_t *sc) |
163 | { | 170 | { |
164 | FILE *fp; | 171 | FILE *fp; |
165 | char buf[1024], *ibuf = buf + 4; | 172 | char buf[1024]; |
166 | 173 | ||
167 | fp = xfopen_for_read("/proc/stat"); | 174 | fp = xfopen_for_read("/proc/stat"); |
168 | 175 | ||
169 | memset(sc, 0, sizeof(*sc)); | 176 | memset(sc, 0, sizeof(*sc)); |
170 | 177 | ||
171 | while (fgets(buf, sizeof(buf), fp)) { | 178 | while (fgets(buf, sizeof(buf), fp)) { |
172 | /* Does the line starts with "cpu "? */ | 179 | int i; |
180 | char *ibuf; | ||
181 | |||
182 | /* Does the line start with "cpu "? */ | ||
173 | if (!starts_with_cpu(buf) || buf[3] != ' ') { | 183 | if (!starts_with_cpu(buf) || buf[3] != ' ') { |
174 | continue; | 184 | continue; |
175 | } | 185 | } |
176 | for (int i = STATS_CPU_USER; i <= STATS_CPU_GUEST; i++) { | 186 | ibuf = buf + 4; |
187 | for (i = STATS_CPU_USER; i <= STATS_CPU_GUEST; i++) { | ||
177 | ibuf = skip_whitespace(ibuf); | 188 | ibuf = skip_whitespace(ibuf); |
178 | sscanf(ibuf, "%"FMT_DATA"u", &sc->vector[i]); | 189 | sscanf(ibuf, "%"FMT_DATA"u", &sc->vector[i]); |
179 | if (i != STATS_CPU_GUEST) { | 190 | if (i != STATS_CPU_GUEST) { |
@@ -233,7 +244,7 @@ static void print_stats_cpu_struct(stats_cpu_pair_t *stats) | |||
233 | { | 244 | { |
234 | cputime_t *p = stats->prev->vector; | 245 | cputime_t *p = stats->prev->vector; |
235 | cputime_t *c = stats->curr->vector; | 246 | cputime_t *c = stats->curr->vector; |
236 | printf(" %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f\n", | 247 | printf(" %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f\n", |
237 | percent_value(p[STATS_CPU_USER] , c[STATS_CPU_USER] , stats->itv), | 248 | percent_value(p[STATS_CPU_USER] , c[STATS_CPU_USER] , stats->itv), |
238 | percent_value(p[STATS_CPU_NICE] , c[STATS_CPU_NICE] , stats->itv), | 249 | percent_value(p[STATS_CPU_NICE] , c[STATS_CPU_NICE] , stats->itv), |
239 | percent_value(p[STATS_CPU_SYSTEM] + p[STATS_CPU_SOFTIRQ] + p[STATS_CPU_IRQ], | 250 | percent_value(p[STATS_CPU_SYSTEM] + p[STATS_CPU_SOFTIRQ] + p[STATS_CPU_IRQ], |
@@ -244,36 +255,40 @@ static void print_stats_cpu_struct(stats_cpu_pair_t *stats) | |||
244 | ); | 255 | ); |
245 | } | 256 | } |
246 | 257 | ||
247 | static void print_stats_dev_struct(const struct stats_dev *p, | 258 | static void cpu_report(stats_cpu_pair_t *stats) |
248 | const struct stats_dev *c, cputime_t itv) | ||
249 | { | 259 | { |
260 | /* Always print a header */ | ||
261 | puts("avg-cpu: %user %nice %system %iowait %steal %idle"); | ||
262 | |||
263 | /* Print current statistics */ | ||
264 | print_stats_cpu_struct(stats); | ||
265 | } | ||
266 | |||
267 | static void print_stats_dev_struct(stats_dev_t *stats_dev, cputime_t itv) | ||
268 | { | ||
269 | stats_dev_data_t *p = &stats_dev->prev_data; | ||
270 | stats_dev_data_t *c = &stats_dev->curr_data; | ||
250 | if (option_mask32 & OPT_z) | 271 | if (option_mask32 & OPT_z) |
251 | if (p->rd_ops == c->rd_ops && p->wr_ops == c->wr_ops) | 272 | if (p->rd_ops == c->rd_ops && p->wr_ops == c->wr_ops) |
252 | return; | 273 | return; |
253 | 274 | ||
254 | printf("%-13s %8.2f %12.2f %12.2f %10llu %10llu \n", c->dname, | 275 | printf("%-13s %8.2f %12.2f %12.2f %10llu %10llu\n", |
255 | percent_value(p->rd_ops + p->wr_ops , | 276 | stats_dev->dname, |
256 | /**/ c->rd_ops + c->wr_ops , itv), | 277 | percent_value(p->rd_ops + p->wr_ops, c->rd_ops + c->wr_ops, itv), |
257 | percent_value(p->rd_sectors, c->rd_sectors, itv) / G.unit.div, | 278 | percent_value(p->rd_sectors, c->rd_sectors, itv) / G.unit.div, |
258 | percent_value(p->wr_sectors, c->wr_sectors, itv) / G.unit.div, | 279 | percent_value(p->wr_sectors, c->wr_sectors, itv) / G.unit.div, |
259 | (c->rd_sectors - p->rd_sectors) / G.unit.div, | 280 | (c->rd_sectors - p->rd_sectors) / G.unit.div, |
260 | (c->wr_sectors - p->wr_sectors) / G.unit.div); | 281 | (c->wr_sectors - p->wr_sectors) / G.unit.div |
261 | } | 282 | ); |
262 | |||
263 | static void cpu_report(stats_cpu_pair_t *stats) | ||
264 | { | ||
265 | /* Always print a header */ | ||
266 | puts("avg-cpu: %user %nice %system %iowait %steal %idle"); | ||
267 | |||
268 | /* Print current statistics */ | ||
269 | print_stats_cpu_struct(stats); | ||
270 | } | 283 | } |
271 | 284 | ||
272 | static void print_devstat_header(void) | 285 | static void print_devstat_header(void) |
273 | { | 286 | { |
274 | printf("Device:%15s%6s%s/s%6s%s/s%6s%s%6s%s\n", "tps", | 287 | printf("Device:%15s%6s%s/s%6s%s/s%6s%s%6s%s\n", |
288 | "tps", | ||
275 | G.unit.str, "_read", G.unit.str, "_wrtn", | 289 | G.unit.str, "_read", G.unit.str, "_wrtn", |
276 | G.unit.str, "_read", G.unit.str, "_wrtn"); | 290 | G.unit.str, "_read", G.unit.str, "_wrtn" |
291 | ); | ||
277 | } | 292 | } |
278 | 293 | ||
279 | /* | 294 | /* |
@@ -285,61 +300,81 @@ static int is_partition(const char *dev) | |||
285 | return ((dev[0] - 's') | (dev[1] - 'd') | (dev[2] - 'a')) == 0 && isdigit(dev[3]); | 300 | return ((dev[0] - 's') | (dev[1] - 'd') | (dev[2] - 'a')) == 0 && isdigit(dev[3]); |
286 | } | 301 | } |
287 | 302 | ||
303 | static stats_dev_t *stats_dev_find_or_new(const char *dev_name) | ||
304 | { | ||
305 | stats_dev_t **curr = &G.stats_dev_list; | ||
306 | |||
307 | while (*curr != NULL) { | ||
308 | if (strcmp((*curr)->dname, dev_name) == 0) | ||
309 | return *curr; | ||
310 | curr = &(*curr)->next; | ||
311 | } | ||
312 | |||
313 | *curr = xzalloc(sizeof(stats_dev_t)); | ||
314 | strncpy((*curr)->dname, dev_name, MAX_DEVICE_NAME); | ||
315 | return *curr; | ||
316 | } | ||
317 | |||
318 | static void stats_dev_free(stats_dev_t *stats_dev) | ||
319 | { | ||
320 | if (stats_dev) { | ||
321 | stats_dev_free(stats_dev->next); | ||
322 | free(stats_dev); | ||
323 | } | ||
324 | } | ||
325 | |||
288 | static void do_disk_statistics(cputime_t itv) | 326 | static void do_disk_statistics(cputime_t itv) |
289 | { | 327 | { |
328 | char buf[128]; | ||
329 | char dev_name[MAX_DEVICE_NAME + 1]; | ||
330 | unsigned long long rd_sec_or_dummy; | ||
331 | unsigned long long wr_sec_or_dummy; | ||
332 | stats_dev_data_t *curr_data; | ||
333 | stats_dev_t *stats_dev; | ||
290 | FILE *fp; | 334 | FILE *fp; |
291 | int rc; | 335 | int rc; |
292 | int i = 0; | ||
293 | char buf[128]; | ||
294 | unsigned major, minor; | ||
295 | unsigned long wr_ops, dummy; /* %*lu for suppress the conversion wouldn't work */ | ||
296 | unsigned long long rd_sec_or_wr_ops; | ||
297 | unsigned long long rd_sec_or_dummy, wr_sec_or_dummy, wr_sec; | ||
298 | struct stats_dev sd; | ||
299 | 336 | ||
300 | fp = xfopen_for_read("/proc/diskstats"); | 337 | fp = xfopen_for_read("/proc/diskstats"); |
301 | |||
302 | /* Read and possibly print stats from /proc/diskstats */ | 338 | /* Read and possibly print stats from /proc/diskstats */ |
303 | while (fgets(buf, sizeof(buf), fp)) { | 339 | while (fgets(buf, sizeof(buf), fp)) { |
304 | rc = sscanf(buf, "%u %u %s %lu %llu %llu %llu %lu %lu %llu %lu %lu %lu %lu", | 340 | sscanf(buf, "%*s %*s %"MAX_DEVICE_NAME_STR"s", dev_name); |
305 | &major, &minor, sd.dname, &sd.rd_ops, | 341 | if (G.dev_name_list) { |
306 | &rd_sec_or_dummy, &rd_sec_or_wr_ops, &wr_sec_or_dummy, | 342 | /* Is device name in list? */ |
307 | &wr_ops, &dummy, &wr_sec, &dummy, &dummy, &dummy, &dummy); | 343 | if (!llist_find_str(G.dev_name_list, dev_name)) |
308 | 344 | continue; | |
309 | switch (rc) { | 345 | } else if (is_partition(dev_name)) { |
310 | case 14: | 346 | continue; |
311 | sd.wr_ops = wr_ops; | ||
312 | sd.rd_sectors = rd_sec_or_wr_ops; | ||
313 | sd.wr_sectors = wr_sec; | ||
314 | break; | ||
315 | case 7: | ||
316 | sd.rd_sectors = rd_sec_or_dummy; | ||
317 | sd.wr_ops = (unsigned long)rd_sec_or_wr_ops; | ||
318 | sd.wr_sectors = wr_sec_or_dummy; | ||
319 | break; | ||
320 | default: | ||
321 | break; | ||
322 | } | 347 | } |
323 | 348 | ||
324 | if (!G.dev_list && !is_partition(sd.dname)) { | 349 | stats_dev = stats_dev_find_or_new(dev_name); |
325 | /* User didn't specify device */ | 350 | curr_data = &stats_dev->curr_data; |
326 | if (!G.show_all && !sd.rd_ops && !sd.wr_ops) { | 351 | |
327 | /* Don't print unused device */ | 352 | rc = sscanf(buf, "%*s %*s %*s %lu %llu %llu %llu %lu %*s %llu", |
328 | continue; | 353 | &curr_data->rd_ops, |
329 | } | 354 | &rd_sec_or_dummy, |
330 | print_stats_dev_struct(&G.saved_stats_dev[i], &sd, itv); | 355 | &curr_data->rd_sectors, |
331 | G.saved_stats_dev[i] = sd; | 356 | &wr_sec_or_dummy, |
332 | i++; | 357 | &curr_data->wr_ops, |
333 | } else { | 358 | &curr_data->wr_sectors); |
334 | /* Is device in device list? */ | 359 | if (rc != 6) { |
335 | if (llist_find_str(G.dev_list, sd.dname)) { | 360 | curr_data->rd_sectors = rd_sec_or_dummy; |
336 | /* Print current statistics */ | 361 | curr_data->wr_sectors = wr_sec_or_dummy; |
337 | print_stats_dev_struct(&G.saved_stats_dev[i], &sd, itv); | 362 | //curr_data->rd_ops = ; |
338 | G.saved_stats_dev[i] = sd; | 363 | curr_data->wr_ops = (unsigned long)curr_data->rd_sectors; |
339 | i++; | ||
340 | } else | ||
341 | continue; | ||
342 | } | 364 | } |
365 | |||
366 | if (!G.dev_name_list /* User didn't specify device */ | ||
367 | && !G.show_all | ||
368 | && curr_data->rd_ops == 0 | ||
369 | && curr_data->wr_ops == 0 | ||
370 | ) { | ||
371 | /* Don't print unused device */ | ||
372 | continue; | ||
373 | } | ||
374 | |||
375 | /* Print current statistics */ | ||
376 | print_stats_dev_struct(stats_dev, itv); | ||
377 | stats_dev->prev_data = *curr_data; | ||
343 | } | 378 | } |
344 | 379 | ||
345 | fclose(fp); | 380 | fclose(fp); |
@@ -354,35 +389,6 @@ static void dev_report(cputime_t itv) | |||
354 | do_disk_statistics(itv); | 389 | do_disk_statistics(itv); |
355 | } | 390 | } |
356 | 391 | ||
357 | static unsigned get_number_of_devices(void) | ||
358 | { | ||
359 | FILE *fp; | ||
360 | char buf[128]; | ||
361 | int rv; | ||
362 | unsigned n = 0; | ||
363 | unsigned long rd_ops, wr_ops; | ||
364 | char dname[MAX_DEVICE_NAME]; | ||
365 | |||
366 | fp = xfopen_for_read("/proc/diskstats"); | ||
367 | |||
368 | while (fgets(buf, sizeof(buf), fp)) { | ||
369 | rv = sscanf(buf, "%*d %*d %s %lu %*u %*u %*u %lu", | ||
370 | dname, &rd_ops, &wr_ops); | ||
371 | if (rv == 2 || is_partition(dname)) | ||
372 | /* A partition */ | ||
373 | continue; | ||
374 | if (!rd_ops && !wr_ops) { | ||
375 | /* Unused device */ | ||
376 | if (!G.show_all) | ||
377 | continue; | ||
378 | } | ||
379 | n++; | ||
380 | } | ||
381 | |||
382 | fclose(fp); | ||
383 | return n; | ||
384 | } | ||
385 | |||
386 | //usage:#define iostat_trivial_usage | 392 | //usage:#define iostat_trivial_usage |
387 | //usage: "[-c] [-d] [-t] [-z] [-k|-m] [ALL|BLOCKDEV...] [INTERVAL [COUNT]]" | 393 | //usage: "[-c] [-d] [-t] [-z] [-k|-m] [ALL|BLOCKDEV...] [INTERVAL [COUNT]]" |
388 | //usage:#define iostat_full_usage "\n\n" | 394 | //usage:#define iostat_full_usage "\n\n" |
@@ -398,7 +404,7 @@ static unsigned get_number_of_devices(void) | |||
398 | int iostat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 404 | int iostat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
399 | int iostat_main(int argc UNUSED_PARAM, char **argv) | 405 | int iostat_main(int argc UNUSED_PARAM, char **argv) |
400 | { | 406 | { |
401 | int opt, dev_num; | 407 | int opt; |
402 | unsigned interval; | 408 | unsigned interval; |
403 | int count; | 409 | int count; |
404 | stats_cpu_t stats_data[2]; | 410 | stats_cpu_t stats_data[2]; |
@@ -427,14 +433,12 @@ int iostat_main(int argc UNUSED_PARAM, char **argv) | |||
427 | argv += optind; | 433 | argv += optind; |
428 | 434 | ||
429 | /* Store device names into device list */ | 435 | /* Store device names into device list */ |
430 | dev_num = 0; | ||
431 | while (*argv && !isdigit(*argv[0])) { | 436 | while (*argv && !isdigit(*argv[0])) { |
432 | if (strcmp(*argv, "ALL") != 0) { | 437 | if (strcmp(*argv, "ALL") != 0) { |
433 | /* If not ALL, save device name */ | 438 | /* If not ALL, save device name */ |
434 | char *dev_name = skip_dev_pfx(*argv); | 439 | char *dev_name = skip_dev_pfx(*argv); |
435 | if (!llist_find_str(G.dev_list, dev_name)) { | 440 | if (!llist_find_str(G.dev_name_list, dev_name)) { |
436 | llist_add_to(&G.dev_list, dev_name); | 441 | llist_add_to(&G.dev_name_list, dev_name); |
437 | dev_num++; | ||
438 | } | 442 | } |
439 | } else { | 443 | } else { |
440 | G.show_all = 1; | 444 | G.show_all = 1; |
@@ -454,13 +458,6 @@ int iostat_main(int argc UNUSED_PARAM, char **argv) | |||
454 | count = xatoi_positive(*argv); | 458 | count = xatoi_positive(*argv); |
455 | } | 459 | } |
456 | 460 | ||
457 | /* Allocate space for device stats */ | ||
458 | if (opt & OPT_d) { | ||
459 | G.saved_stats_dev = xzalloc(sizeof(G.saved_stats_dev[0]) * | ||
460 | (dev_num ? dev_num : get_number_of_devices()) | ||
461 | ); | ||
462 | } | ||
463 | |||
464 | if (opt & OPT_m) { | 461 | if (opt & OPT_m) { |
465 | G.unit.str = " MB"; | 462 | G.unit.str = " MB"; |
466 | G.unit.div = 2048; | 463 | G.unit.div = 2048; |
@@ -530,8 +527,8 @@ int iostat_main(int argc UNUSED_PARAM, char **argv) | |||
530 | } | 527 | } |
531 | 528 | ||
532 | if (ENABLE_FEATURE_CLEAN_UP) { | 529 | if (ENABLE_FEATURE_CLEAN_UP) { |
533 | llist_free(G.dev_list, NULL); | 530 | llist_free(G.dev_name_list, NULL); |
534 | free(G.saved_stats_dev); | 531 | stats_dev_free(G.stats_dev_list); |
535 | free(&G); | 532 | free(&G); |
536 | } | 533 | } |
537 | 534 | ||