On Sat, May 12, 2001 at 05:42:01PM +0400, Sergey A. Osokin wrote:
> 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.

I have rewritten devstat_compute_statistics().
Please see the attachment.
If you need a patch-version for libdevstat, just say about.
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 = 1,
        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
};

/*
 *  How to use this function?
 *
 *  long double total_bytes;
 *
 *  devstat_compute_statistics(&cur.dinfo->devices[di], &last.dinfo->devices[di],
 *                              busy_seconds, DEVSTAT_TOTAL_BYTES, &total_bytes, 0);
 *
 *  DEVSTAT_TOTAL_BYTES - is what you need.
 *  total_bytes - where you need.
 *
 *  Wrapper for
 *  compute_stats(current, previous, etime, total_bytes,
 *              total_transfers, total_blocks,
 *              kb_per_transfer, transfers_per_second,
 *              mb_per_second, blocks_per_second,
 *              ms_per_transaction);
 *
 *  looks like this:
 *
 *  devstat_compute_statistics(current, previous, etime,
 *              DEVSTAT_TOTAL_BYTES, total_bytes,
 *              DEVSTAT_TOTAL_TRANSFERS, total_transfers,
 *              DEVSTAT_TOTAL_BLOCKS, total_blocks,
 *              DEVSTAT_TOTAL_TRANSFER, kb_per_transfer,
 *              DEVSTAT_TRANSFERS_PER_SECOND, transfers_per_second,
 *              DEVSTAT_MB_PER_SECOND, mb_per_second,
 *              DEVSTAT_BLOCKS_PER_SECOND, blocks_per_second,
 *              DEVSTAT_MS_PER_TRANSACTION, ms_per_transaction,
 *              0);
 */

long double
devstat_compute_statistics(struct devstat *current, struct devstat *previous,
                long double etime, ...)
{
        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";
        va_list ap;
        enum DEVSTAT_METRIC metric;
        long double *destination;

        /*
         * 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);

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

        totalbytes = totalbytes_read + totalbytes_write;

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

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

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

        totaltransfers = totaltransfers_read + totaltransfers_write + 
totaltransfers_other;

        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;
        }

        va_start(ap, etime);
        while ((metric = (enum DEVSTAT_METRIC)va_arg(ap, enum DEVSTAT_METRIC)) != 0 ) {
                if ((destination = va_arg (ap, long double*)) != NULL) {

                        switch (metric) {
                                case DEVSTAT_TOTAL_BYTES_READ:
                                        *destination = totalbytes_read;

                                case DEVSTAT_TOTAL_BYTES_WRITE:
                                        *destination = totalbytes_write;

                                case DEVSTAT_TOTAL_BYTES:
                                        *destination = totalbytes;

                                case DEVSTAT_TOTAL_TRANSFERS_READ:
                                        *destination = totaltransfers_read;

                                case DEVSTAT_TOTAL_TRANSFERS_WRITE:
                                        *destination = totaltransfers_write;

                                case DEVSTAT_TOTAL_TRANSFERS_OTHER:
                                        *destination = totaltransfers_other;

                                case DEVSTAT_TOTAL_TRANSFERS:
                                        *destination = totaltransfers;

                                case DEVSTAT_TRANSFERS_PER_SECOND:
                                        if (etime > 0.0)
                                                *destination = totaltransfers/etime;
                                        else
                                                *destination = 0.0;

                                case DEVSTAT_TRANSFERS_PER_SECOND_READ:
                                        if (etime > 0.0)
                                                *destination = 
totaltransfers_read/etime;
                                        else
                                                *destination = 0.0;

                                case DEVSTAT_TRANSFERS_PER_SECOND_WRITE:
                                        if (etime > 0.0)
                                                *destination = 
totaltransfers_write/etime;
                                        else
                                                *destination = 0.0;

                                case DEVSTAT_TRANSFERS_PER_SECOND_OTHER:
                                        if (etime > 0.0)
                                                *destination = 
totaltransfers_other/etime;
                                        else
                                                *destination = 0.0;

                                case DEVSTAT_KB_PER_TRANSFER:
                                        if (totaltransfers > 0)
                                                *destination = 
totalbytes/(1024*totaltransfers);
                                        else
                                                *destination = 0.0;

                                case DEVSTAT_KB_PER_TRANSFER_READ:
                                        if (totaltransfers_read > 0)
                                                *destination = 
totalbytes_read/(1024*totaltransfers_read);
                                        else
                                                *destination = 0.0;

                                case DEVSTAT_KB_PER_TRANSFER_WRITE:
                                        if (totaltransfers_write > 0)
                                                *destination = 
totalbytes_write/(1024*totaltransfers_write);
                                        else
                                                *destination = 0.0;

                                case DEVSTAT_MB_PER_SECOND:
                                        if (etime > 0.0)
                                                *destination = 
totalbytes/((1024*1024)*etime);
                                        else
                                                *destination = 0.0;

                                case DEVSTAT_MB_PER_SECOND_READ:
                                        if (etime > 0.0)
                                                *destination = 
totalbytes_read/((1024*1024)*etime);
                                        else
                                                *destination = 0.0;

                                case DEVSTAT_MB_PER_SECOND_WRITE:
                                        if (etime > 0.0)
                                                *destination = 
totalbytes_write/((1024*1024)*etime);
                                        else
                                                *destination = 0.0;

                                case DEVSTAT_TOTAL_BLOCKS:
                                        *destination = totalblocks;

                                case DEVSTAT_TOTAL_BLOCKS_READ:
                                        *destination = totalblocks_read;

                                case DEVSTAT_TOTAL_BLOCKS_WRITE:
                                        *destination = totalblocks_write;

                                case DEVSTAT_BLOCKS_PER_SECOND:
                                        if (etime > 0.0)
                                                *destination = totalblocks/etime;
                                        else
                                                *destination = 0.0;

                                case DEVSTAT_BLOCKS_PER_SECOND_READ:
                                        if (etime > 0.0)
                                                *destination = totalblocks_read/etime;
                                        else
                                                *destination = 0.0;

                                case DEVSTAT_BLOCKS_PER_SECOND_WRITE:
                                        if (etime > 0.0)
                                                *destination = totalblocks_write/etime;
                                        else
                                                *destination = 0.0;

                                case DEVSTAT_MS_PER_TRANSACTION:
                                        if (totaltransfers > 0)
                                                *destination = 
(etime*1000)/totaltransfers;
                                        else
                                                *destination = 0.0;

                                case DEVSTAT_MS_PER_TRANSACTION_READ:
                                        if (totaltransfers_read > 0)
                                                *destination = 
(etime*1000)/totaltransfers_read;
                                        else
                                                *destination = 0.0;

                                case DEVSTAT_MS_PER_TRANSACTION_WRITE:
                                        if (totaltransfers_write > 0)
                                                *destination = 
(etime*1000)/totaltransfers_write;
                                        else
                                                *destination = 0.0;
                                default:
                                        *destination = 0.0;
                        }
                } else {
                        sprintf(devstat_errbuf, "%s: variable is not long double *",
                        func_name);
                        return(-1);
                }
        }

        va_end(ap);

        return(0);
}

Reply via email to