//
// Copyright (c) 1995, 1996, 1997-2002 by Brian Grayson (bgrayson@netbsd.org)
//
// This file was written by Brian Grayson for the NetBSD and xosview
// projects.
// This file may be distributed under terms of the GPL or of the BSD
// license, whichever you choose. The full license notices are
// contained in the files COPYING.GPL and COPYING.BSD, which you
// should have received. If not, contact one of the xosview
// authors for a copy.
//
// $Id$
//
#include <err.h> // For err() and warn(), etc. BCG
#include <stdlib.h> // For use of atoi BCG
#include "general.h"
#include "diskmeter.h"
#include "kernel.h" // For NetBSD-specific icky (but handy) kvm_ code. BCG
CVSID("$Id$");
CVSID_DOT_H(DISKMETER_H_CVSID);
DiskMeter::DiskMeter( XOSView *parent, float max )
: FieldMeterGraph( parent, 2, "DISK", "XFER/IDLE" ){
// The setting of the priority will be done in checkResources(). BCG
dodecay_ = 0;
kernelHasStats_ = BSDDiskInit();
if (!kernelHasStats_)
{
warnx(
"!!! The kernel does not seem to have the symbols needed for the DiskMeter."
);
#if defined(XOSVIEW_NETBSD)
warnx(
" (A 1.2 kernel or above is probably needed)"
);
#else
# if defined(XOSVIEW_FREEBSD)
warnx(
" (You are probably running a kernel newer than 3.0-19980804-SNAP)"
);
# else
warnx(
" (You are probably running a newer or older kernel than any yet used with xosview)"
);
# endif
#endif
warnx("!!! The DiskMeter has been disabled.");
disableMeter ();
}
prevBytes = 0;
maxBandwidth_ = max;
total_ = max;
getstats();
/* Since at the first call, it will look like we transferred a
gazillion bytes, let's reset total_ again and do another
call. This will force total_ to be something reasonable. */
total_ = max;
IntervalTimerStart();
getstats();
/* By doing this check, we eliminate the startup situation where
all fields are 0, and total is 0, leading to nothing being drawn
on the meter. So, make it look like nothing was transferred,
out of a total of 1 bytes. */
if (total_ < 1.0)
{
total_ = (float)1.0;
fields_[1] = total_;
}
}
DiskMeter::~DiskMeter( void ){
}
void DiskMeter::checkResources( void ){
FieldMeterGraph::checkResources();
if (kernelHasStats_) {
setfieldcolor( 0, parent_->getResource("diskUsedColor") );
setfieldcolor( 1, parent_->getResource("diskIdleColor") );
priority_ = atoi (parent_->getResource("diskPriority"));
dodecay_ = parent_->isResourceTrue("diskDecay");
useGraph_ = parent_->isResourceTrue("diskGraph");
SetUsedFormat (parent_->getResource("diskUsedFormat"));
}
fields_[0] = 0.0;
fields_[1] = 0.0;
}
void DiskMeter::checkevent( void ){
getstats();
drawfields();
}
void DiskMeter::getstats( void ){
IntervalTimerStop();
unsigned long long currBytes = 0;
// Reset to desired full-scale settings.
total_ = maxBandwidth_;
if (kernelHasStats_) {
BSDGetDiskXFerBytes (&currBytes);
#if DEBUG
printf ("currBytes is %#x %#0x\n", (int) (currBytes >> 32), (int)
(currBytes & 0xffffffff));
#endif
}
/* Adjust this to bytes/second. */
fields_[0] = (currBytes-prevBytes)/IntervalTimeInSecs();
/* Adjust in case of first call. */
if (fields_[0] < 0) fields_[0] = 0.0;
// Adjust total_ if needed.
if (fields_[0] > total_)
total_ = fields_[0];
fields_[1] = total_ - fields_[0];
if (fields_[0] < 0.0)
fprintf (stderr, "diskmeter: fields[0] of %f is < 0!\n", fields_[0]);
if (fields_[1] < 0.0)
fprintf (stderr, "diskmeter: fields[1] of %f is < 0!\n", fields_[1]);
setUsed ( fields_[0], total_);
#ifdef HAVE_DEVSTAT
/* The devstat library provides a differential value already,
* so we should compare against 0 each time. */
prevBytes = currBytes = 0;
#else
prevBytes = currBytes;
#endif
IntervalTimerStart();
}
syntax highlighted by Code2HTML, v. 0.9.1