/*
* Copyright (c) 1996 John M. Vinopal
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project
* by John M. Vinopal.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* Missing from <sys/time.h> */
#define timerset(tvp, uvp) do { \
((uvp)->tv_sec = (tvp)->tv_sec); \
((uvp)->tv_usec = (tvp)->tv_usec); \
} while (0)
/*
* Take the delta between the present values and the last recorded
* values, storing the present values in the 'last' structure, and
* the delta values in the 'cur' structure.
*/
void
drvswap(void)
{
u_int64_t tmp;
size_t i;
#define SWAP(fld) do { \
tmp = cur.fld; \
cur.fld -= last.fld; \
last.fld = tmp; \
} while (0)
for (i = 0; i < ndrive; i++) {
struct timeval tmp_timer;
if (!cur.select[i])
continue;
/*
* When a drive is replaced with one of the same
* name, the previous statistics are invalid. Try
* to detect this by validating counters and timestamp
*/
if ((cur.rxfer[i] == 0 && cur.wxfer[i] == 0)
|| cur.rxfer[i] - last.rxfer[i] > INT64_MAX
|| cur.wxfer[i] - last.wxfer[i] > INT64_MAX
|| cur.seek[i] - last.seek[i] > INT64_MAX
|| (cur.timestamp[i].tv_sec == 0 &&
cur.timestamp[i].tv_usec == 0)) {
void
cpuswap(void)
{
double etime;
u_int64_t tmp;
int i, state;
for (i = 0; i < CPUSTATES; i++)
SWAP(cp_time[i]);
etime = 0;
for (state = 0; state < CPUSTATES; ++state) {
etime += cur.cp_time[state];
}
if (etime == 0)
etime = 1;
etime /= hz;
etime /= cur.cp_ncpu;
cur.cp_etime = etime;
}
#undef DELTA
#undef SWAP
/*
* Read the drive statistics for each drive in the drive list.
* Also collect statistics for tty i/o and CPU ticks.
*/
void
drvreadstats(void)
{
size_t size, i, j, count;
int mib[3];
for (i = 0, j = 0; i < ndrive && j < count; i++) {
/*
* skip removed entries
*
* we cannot detect entries replaced with
* devices of the same name (e.g. unplug/replug).
*/
if (strcmp(cur.name[i], drives[j].name)) {
cur.select[i] = 0;
continue;
}
COPYF(rxfer, i, j);
COPYF(wxfer, i, j);
COPYF(seek, i, j);
COPYF(rbytes, i, j);
COPYF(wbytes, i, j);
COPYT(wait, i, j);
COPYT(time, i, j);
COPYT(waitsum, i, j);
COPYT(busysum, i, j);
COPYT(timestamp, i, j);
/*
* Perform all of the initialization and memory allocation needed to
* track drive statistics.
*/
int
drvinit(int selected)
{
struct clockinfo clockinfo;
size_t size, i;
static int once = 0;
int mib[3];