From ef96d4b7a9b4d75885e7773a2430560c72f9b2aa Mon Sep 17 00:00:00 2001 From: ken Date: Sat, 18 Aug 2001 05:46:59 +0000 Subject: Implement compute_stats() in terms of devstat_compute_statistics(). This gets rid of the duplicated code in compute_stats(). Add a new DSM_SKIP statistic type for devstat_compute_statistics() that causes the subsequent variable argument to be skipped. Thanks to Sergey Osokin for coding up my idea/code fragment. Submitted by: "Sergey A. Osokin" --- lib/libdevstat/devstat.3 | 12 +++++ lib/libdevstat/devstat.c | 132 ++++++++++------------------------------------- lib/libdevstat/devstat.h | 1 + 3 files changed, 41 insertions(+), 104 deletions(-) diff --git a/lib/libdevstat/devstat.3 b/lib/libdevstat/devstat.3 index 102d582..319b37e 100644 --- a/lib/libdevstat/devstat.3 +++ b/lib/libdevstat/devstat.3 @@ -762,6 +762,18 @@ and .Va current . As above, this is not the true number of milliseconds per transaction, but rather the average rate of write transaction completion. +.It DSM_SKIP +type: N/A +.Pp +If you do not need a result from +.Fn devstat_compute_statistics , +just put +.Va DSM_SKIP +as first (type) parameter and +.Va NULL +as second parameter. +This can be useful in scenarios where the statistics to be calculated +are determined at run time. .El .Pp .Fn compute_stats diff --git a/lib/libdevstat/devstat.c b/lib/libdevstat/devstat.c index 79512a5..7db6b99 100644 --- a/lib/libdevstat/devstat.c +++ b/lib/libdevstat/devstat.c @@ -49,7 +49,8 @@ typedef enum { DEVSTAT_ARG_NOTYPE, DEVSTAT_ARG_UINT64, - DEVSTAT_ARG_LD + DEVSTAT_ARG_LD, + DEVSTAT_ARG_SKIP } devstat_arg_type; char devstat_errbuf[DEVSTAT_ERRBUF_SIZE]; @@ -109,7 +110,8 @@ struct devstat_args { { DSM_BLOCKS_PER_SECOND_WRITE, DEVSTAT_ARG_LD }, { DSM_MS_PER_TRANSACTION, DEVSTAT_ARG_LD }, { DSM_MS_PER_TRANSACTION_READ, DEVSTAT_ARG_LD }, - { DSM_MS_PER_TRANSACTION_WRITE, DEVSTAT_ARG_LD } + { DSM_MS_PER_TRANSACTION_WRITE, DEVSTAT_ARG_LD }, + { DSM_SKIP, DEVSTAT_ARG_SKIP } }; static char *namelist[] = { @@ -1129,89 +1131,24 @@ compute_stats(struct devstat *current, struct devstat *previous, long double *mb_per_second, long double *blocks_per_second, long double *ms_per_transaction) { - u_int64_t totalbytes, totaltransfers, totalblocks; - char *func_name = "compute_stats"; - - /* - * current is the only mandatory field. - */ - if (current == NULL) { - snprintf(devstat_errbuf, sizeof(devstat_errbuf), - "%s: current stats structure was NULL", - func_name); - return(-1); - } - - totalbytes = (current->bytes_written + current->bytes_read) - - ((previous) ? (previous->bytes_written + - previous->bytes_read) : 0); - - if (total_bytes) - *total_bytes = totalbytes; - - totaltransfers = (current->num_reads + - current->num_writes + - current->num_other) - - ((previous) ? - (previous->num_reads + - previous->num_writes + - previous->num_other) : 0); - if (total_transfers) - *total_transfers = totaltransfers; - - if (transfers_per_second) { - if (etime > 0.0) { - *transfers_per_second = totaltransfers; - *transfers_per_second /= etime; - } else - *transfers_per_second = 0.0; - } - - if (kb_per_transfer) { - *kb_per_transfer = totalbytes; - *kb_per_transfer /= 1024; - if (totaltransfers > 0) - *kb_per_transfer /= totaltransfers; - else - *kb_per_transfer = 0.0; - } - - if (mb_per_second) { - *mb_per_second = totalbytes; - *mb_per_second /= 1024 * 1024; - if (etime > 0.0) - *mb_per_second /= etime; - else - *mb_per_second = 0.0; - } - - totalblocks = totalbytes; - if (current->block_size > 0) - totalblocks /= current->block_size; - else - totalblocks /= 512; - - if (total_blocks) - *total_blocks = totalblocks; - - if (blocks_per_second) { - *blocks_per_second = totalblocks; - if (etime > 0.0) - *blocks_per_second /= etime; - else - *blocks_per_second = 0.0; - } - - if (ms_per_transaction) { - if (totaltransfers > 0) { - *ms_per_transaction = etime; - *ms_per_transaction /= totaltransfers; - *ms_per_transaction *= 1000; - } else - *ms_per_transaction = 0.0; - } - - return(0); + return(devstat_compute_statistics(current, previous, etime, + total_bytes ? DSM_TOTAL_BYTES : DSM_SKIP, + total_bytes, + total_transfers ? DSM_TOTAL_TRANSFERS : DSM_SKIP, + total_transfers, + total_blocks ? DSM_TOTAL_BLOCKS : DSM_SKIP, + total_blocks, + kb_per_transfer ? DSM_KB_PER_TRANSFER : DSM_SKIP, + kb_per_transfer, + transfers_per_second ? DSM_TRANSFERS_PER_SECOND : DSM_SKIP, + transfers_per_second, + mb_per_second ? DSM_MB_PER_SECOND : DSM_SKIP, + mb_per_second, + blocks_per_second ? DSM_BLOCKS_PER_SECOND : DSM_SKIP, + blocks_per_second, + ms_per_transaction ? DSM_MS_PER_TRANSACTION : DSM_SKIP, + ms_per_transaction, + DSM_NONE)); } long double @@ -1309,35 +1246,22 @@ devstat_compute_statistics(struct devstat *current, struct devstat *previous, switch (devstat_arg_list[metric].argtype) { case DEVSTAT_ARG_UINT64: destu64 = (u_int64_t *)va_arg(ap, u_int64_t *); - if (destu64 == NULL) { - snprintf(devstat_errbuf, sizeof(devstat_errbuf), - "%s: argument type not u_int64_t * or " - "argument type missing", func_name); - retval = -1; - goto bailout; - break; /* NOTREACHED */ - } break; case DEVSTAT_ARG_LD: destld = (long double *)va_arg(ap, long double *); - if (destld == NULL) { - snprintf(devstat_errbuf, sizeof(devstat_errbuf), - "%s: argument type not long double * " - "or argument type missing", func_name); - retval = -1; - goto bailout; - break; /* NOTREACHED */ - } + break; + case DEVSTAT_ARG_SKIP: + destld = (long double *)va_arg(ap, long double *); break; default: - snprintf(devstat_errbuf, sizeof(devstat_errbuf), - "%s: unknown argument type %d", func_name, - devstat_arg_list[metric].argtype); retval = -1; goto bailout; break; /* NOTREACHED */ } + if (devstat_arg_list[metric].argtype == DEVSTAT_ARG_SKIP) + continue; + switch (metric) { case DSM_TOTAL_BYTES: *destu64 = totalbytes; diff --git a/lib/libdevstat/devstat.h b/lib/libdevstat/devstat.h index ec638c1..49d8f2d 100644 --- a/lib/libdevstat/devstat.h +++ b/lib/libdevstat/devstat.h @@ -74,6 +74,7 @@ typedef enum { DSM_MS_PER_TRANSACTION, DSM_MS_PER_TRANSACTION_READ, DSM_MS_PER_TRANSACTION_WRITE, + DSM_SKIP, DSM_MAX } devstat_metric; -- cgit v1.1