On Fri, May 11, 2001 at 07:35:50PM +0200, Poul-Henning Kamp wrote:
> In message <[EMAIL PROTECTED]>, "Sergey A. Osokin" writes:
> 
> >Hello.
> >2 monthes ago I talked in -current about new features for libdevstat.
> >Here is a new function, which calculate more statistics then 
> >existing compute_stats(). (compute_stats() calculate only average
> >results, not read/write results).
> >Please see my first step. Comments are welcome.
> 
> I really don't think this is the way...
> 
> I would far rather see:
> 
>       enum DEVSTAT_METRIC {
>               DEVSTAT_BYTES,
>               DEVSTAT_BYTES_READ,
>               DEVSTAT_BYTES_WRITE,
>               ...
>       }
> 
>       int
>       devstat_compute_statistics(
>           struct devstat *current,
>           struct devstat *previous,
>           enum DEVSTAT_METRIC metric,
>           double *destination);
> 
> Since that can be extended with new metrics without changing
> the ABI...

OK. Please see attachment.
Thanks.
-- 

Rgdz,                                /"\ 
Sergey Osokin aka oZZ,               \ /  ASCII RIBBON CAMPAIGN
[EMAIL PROTECTED]                    X     AGAINST HTML MAIL
http://freebsd.org.ru/~osa/          / \
enum DEVSTAT_METRIC {
        DEVSTAT_TOTAL_BYTES,
        DEVSTAT_TOTAL_BYTES_READ,
        DEVSTAT_TOTAL_BYTES_WRITE,
        DEVSTAT_TOTAL_TRANSFERS,
        DEVSTAT_TOTAL_TRANSFERS_READ,
        DEVSTAT_TOTAL_TRANSFERS_WRITE,
        DEVSTAT_TOTAL_TRANSFERS_OTHER,
        DEVSTAT_TOTAL_BLOCKS,
        DEVSTAT_TOTAL_BLOCKS_READ,
        DEVSTAT_TOTAL_BLOCKS_WRITE,
        DEVSTAT_KB_PER_TRANSFER,
        DEVSTAT_KB_PER_TRANSFER_READ,
        DEVSTAT_KB_PER_TRANSFER_WRITE,
        DEVSTAT_TRANSFERS_PER_SECOND,
        DEVSTAT_TRANSFERS_PER_SECOND_READ,
        DEVSTAT_TRANSFERS_PER_SECOND_WRITE,
        DEVSTAT_TRANSFERS_PER_SECOND_OTHER,
        DEVSTAT_MB_PER_SECOND,
        DEVSTAT_MB_PER_SECOND_READ,
        DEVSTAT_MB_PER_SECOND_WRITE,
        DEVSTAT_BLOCKS_PER_SECOND,
        DEVSTAT_BLOCKS_PER_SECOND_READ,
        DEVSTAT_BLOCKS_PER_SECOND_WRITE,
        DEVSTAT_MS_PER_TRANSACTION,
        DEVSTAT_MS_PER_TRANSACTION_READ,
        DEVSTAT_MS_PER_TRANSACTION_WRITE
};

int
devstat_compute_statistics(struct devstat *current, struct devstat *previous,
                long double etime, enum DEVSTAT_METRIC metric,
                long double *destination)
{
        u_int64_t totalbytes, totalbytes_read, totalbytes_write;
        u_int64_t totaltransfers, totaltransfers_read, totaltransfers_write, 
totaltransfers_other;
        u_int64_t totalblocks, totalblocks_read, totalblocks_write;
        char *func_name = "devstat_compute_statistics";

        /*
         * current is the only mandatory field.
         */

        if (current == NULL) {
                sprintf(devstat_errbuf, "%s: current stats structure was NULL",
                        func_name);
                return(-1);
        }

        totalbytes_read = current->bytes_read - ((previous) ? previous->bytes_read : 
0);

        if (metric == DEVSTAT_TOTAL_BYTES_READ) {
                *destination = totalbytes_read;
                return 0;
        }

        totalbytes_write = current->bytes_written - ((previous) ? 
previous->bytes_written : 0);

        if (metric == DEVSTAT_TOTAL_BYTES_WRITE) {
                *destination = totalbytes_write;
                return 0;
        }

/*
        totalbytes = (current->bytes_written + current->bytes_read) -
                ((previous) ? (previous->bytes_written +
                        previous->bytes_read) : 0);
*/

        totalbytes = totalbytes_read + totalbytes_write;

        if (metric == DEVSTAT_TOTAL_BYTES) {
                *destination = totalbytes;
                return 0;
        }

        totaltransfers_read = current->num_reads - ((previous) ? (previous->num_reads) 
: 0);

        if (metric == DEVSTAT_TOTAL_TRANSFERS_READ) {
                *destination = totaltransfers_read;
                return 0;
        }

        totaltransfers_write = current->num_writes - ((previous) ? 
(previous->num_writes) : 0);

        if (metric == DEVSTAT_TOTAL_TRANSFERS_WRITE) {
                *destination = totaltransfers_write;
                return 0;
        }

        totaltransfers_other = current->num_other - ((previous) ? 
(previous->num_other) : 0);

        if (metric == DEVSTAT_TOTAL_TRANSFERS_OTHER) {
                *destination = totaltransfers_other;
                return 0;
        }
/*
        totaltransfers = (current->num_reads +
                          current->num_writes +
                          current->num_other) -
                        ((previous) ?
                         (previous->num_reads +
                          previous->num_writes +
                          previous->num_other) : 0);
*/

        totaltransfers = totaltransfers_read + totaltransfers_write + 
totaltransfers_other;

        if (metric == DEVSTAT_TOTAL_TRANSFERS) {
                *destination = totaltransfers;
                return 0;
        }

        if (metric == DEVSTAT_TRANSFERS_PER_SECOND) {
                if (etime > 0.0) {
                        *destination = totaltransfers;
                        *destination /= etime;
                        return 0;
                } else {
                        *destination = 0.0;
                        return 0;
                }
        }

        if (metric == DEVSTAT_TRANSFERS_PER_SECOND_READ) {
                if (etime > 0.0) {
                        *destination = totaltransfers_read;
                        *destination /= etime;
                        return 0;
                } else {
                        *destination = 0.0;
                        return 0;
                }
        }

        if (metric == DEVSTAT_TRANSFERS_PER_SECOND_WRITE) {
                if (etime > 0.0) {
                        *destination = totaltransfers_write;
                        *destination /= etime;
                        return 0;
                } else {
                        *destination = 0.0;
                        return 0;
                }
        }

        if (metric == DEVSTAT_TRANSFERS_PER_SECOND_OTHER) {
                if (etime > 0.0) {
                        *destination = totaltransfers_other;
                        *destination /= etime;
                        return 0;
                } else {
                        *destination = 0.0;
                        return 0;
                }
        }

        if (metric == DEVSTAT_KB_PER_TRANSFER) {
                *destination = totalbytes;
                *destination /= 1024;
                if (totaltransfers > 0) {
                        *destination /= totaltransfers;
                        return 0;
                } else {
                        *destination = 0.0;
                        return 0;
                }
        }

        if (metric == DEVSTAT_KB_PER_TRANSFER_READ) {
                *destination = totalbytes_read;
                *destination /= 1024;
                if (totaltransfers_read > 0) {
                        *destination /= totaltransfers_read;
                        return 0;
                } else {
                        *destination = 0.0;
                        return 0;
                }
        }

        if (metric == DEVSTAT_KB_PER_TRANSFER_WRITE) {
                *destination = totalbytes_write;
                *destination /= 1024;
                if (totaltransfers_write > 0) {
                        *destination /= totaltransfers_write;
                        return 0;
                } else {
                        *destination = 0.0;
                        return 0;
                }
        }

        if (metric == DEVSTAT_MB_PER_SECOND) {
                *destination = totalbytes;
                *destination /= 1024 * 1024;
                if (etime > 0.0) {
                        *destination /= etime;
                        return 0;
                } else {
                        *destination = 0.0;
                        return 0;
                }
        }

        if (metric == DEVSTAT_MB_PER_SECOND_READ) {
                *destination = totalbytes_read;
                *destination /= 1024 * 1024;
                if (etime > 0.0) {
                        *destination /= etime;
                        return 0;
                } else {
                        *destination = 0.0;
                        return 0;
                }
        }

        if (metric == DEVSTAT_MB_PER_SECOND_WRITE) {
                *destination = totalbytes_write;
                *destination /= 1024 * 1024;
                if (etime > 0.0) {
                        *destination /= etime;
                        return 0;
                } else {
                        *destination = 0.0;
                        return 0;
                }
        }

        totalblocks = totalbytes;
        totalblocks_read = totalbytes_read;
        totalblocks_write = totalbytes_write;

        if (current->block_size > 0) {
                totalblocks /= current->block_size;
                totalblocks_read /= current->block_size;
                totalblocks_write /= current->block_size;
        }
        else {
                totalblocks /= 512;
                totalblocks_read /= 512;
                totalblocks_write /= 512;
        }

        if (metric == DEVSTAT_TOTAL_BLOCKS) {
                *destination = totalblocks;
                return 0;
        }

        if (metric == DEVSTAT_TOTAL_BLOCKS_READ) {
                *destination = totalblocks_read;
                return 0;
        }

        if (metric == DEVSTAT_TOTAL_BLOCKS_WRITE) {
                *destination = totalblocks_write;
                return 0;
        }

        if (metric  == DEVSTAT_BLOCKS_PER_SECOND) {
                *destination = totalblocks;
                if (etime > 0.0) {
                        *destination /= etime;
                        return 0;
                } else {
                        *destination = 0.0;
                        return 0;
                }
        }

        if (metric  == DEVSTAT_BLOCKS_PER_SECOND_READ) {
                *destination = totalblocks_read;
                if (etime > 0.0) {
                        *destination /= etime;
                        return 0;
                } else {
                        *destination = 0.0;
                        return 0;
                }
        }

        if (metric  == DEVSTAT_BLOCKS_PER_SECOND_WRITE) {
                *destination = totalblocks_write;
                if (etime > 0.0) {
                        *destination /= etime;
                        return 0;
                } else {
                        *destination = 0.0;
                        return 0;
                }
        }

        if (metric  == DEVSTAT_MS_PER_TRANSACTION) {
                if (totaltransfers > 0) {
                        *destination = etime;
                        *destination /= totaltransfers;
                        *destination *= 1000;
                        return 0;
                } else {
                        *destination = 0.0;
                        return 0;
                }
        }

        if (metric  == DEVSTAT_MS_PER_TRANSACTION_READ) {
                if (totaltransfers_read > 0) {
                        *destination = etime;
                        *destination /= totaltransfers_read;
                        *destination *= 1000;
                        return 0;
                } else {
                        *destination = 0.0;
                        return 0;
                }
        }

        if (metric  == DEVSTAT_MS_PER_TRANSACTION_WRITE) {
                if (totaltransfers_write > 0) {
                        *destination = etime;
                        *destination /= totaltransfers_write;
                        *destination *= 1000;
                        return 0;
                } else {
                        *destination = 0.0;
                        return 0;
                }
        }

        return(0);
}

Reply via email to