EVCOUNT(9) OpenBSD Kernel Manual EVCOUNT(9)NAME
evcount, evcount_attach, evcount_detach - generic interrupt and event
counter kernel API
SYNOPSIS
#include <sys/evcount.h>
void
evcount_attach(struct evcount *ec, const char *name, void *data);
void
evcount_detach(struct evcount *ec);
DESCRIPTION
The evcount API provides an interface for generic event and interrupt
counting, whose statistics are made available to machine-independent
sysctl(3) nodes.
Overview
With evcount, an architecture can collect interrupt counting for any
device. All registered counters will be made available under the
kern.evcount sysctl(3) node as a flat list. The following is a sample
list of counters provided by some common architectures:
clock Interrupt counter for the system clock
stat Second-level interrupt decrementer counter
rtc Real-time clock counter
prof System profiler counter
pciide0 PCI IDE controller counter (see pciide(4))
uhci0 USB 1.0 controller counter (see usb(4))
See intro(4) for a list of devices for any of which evcount may track
interrupt counting.
The systat(1) and vmstat(8) utilities can be used to view interrupts
collected by evcount.
The API
The evcount structure has the following definition:
struct evcount {
u_int64_t ec_count; /* main counter */
int ec_id; /* counter ID */
const char *ec_name; /* counter name */
void *ec_data; /* user data */
TAILQ_ENTRY(evcount) next;
};
The evcount_attach(ec, name, data) function adds the given event counter
to the system's counter list. name provides the counter name, which is
modeled after a device, such as ``clock'' or ``pciide0''. data provides
a chunk of data that will be made available through the sysctl(3) call.
The evcount_detach(ec) function removes the given event counter ec from
the counter list.
EXAMPLES
The following is an outline of code that provides routines to register
and de-register interrupt handlers for devices, plugging the counting of
interrupts generated by them during system operation into the evcount
framework.
#include <sys/evcount.h>
#include <machine/intr.h>
/*
* machine/intr.h provides a structure, intrhand, which is
* machine-dependent but is usually similar to this:
*
* struct intrhand {
* int (*ih_fun)(void *);
* void *ih_arg;
* int ih_level;
* struct intrhand *ih_next;
* int ih_irq;
* struct evcount ih_count;
* }
*/
/*
* Register an interrupt handler.
*/
void *
intr_establish(void *lcv, int irq, int type, int level,
int (*ih_fun)(void *), void *ih_arg, char *name)
{
struct intrhand *ih, **p;
/*
* Allocate memory for the handler, sanity-check incoming
* values (IRQ#, etc.), and link the handler into
* machine-dependent data structures.
*/
/*
* Fill out the handler.
*/
ih->ih_fun = ih_fun;
ih->ih_arg = ih_arg;
ih->ih_next = NULL;
ih->ih_level = level;
ih->ih_irq = irq;
/*
* Attach it.
*/
evcount_attach(&ih->ih_count, name, &ih->ih_irq);
return (ih);
}
/*
* Deregister an interrupt handler.
*/
void
intr_disestablish(void *lcp, void *arg)
{
struct intrhand *ih = arg;
/*
* Sanity-check incoming values (IRQ, etc.) and remove
* the interrupt handler from machine-dependent data
* structures.
*/
evcount_detach(&ih->ih_count);
/*
* Free up memory and install a null interrupt handler.
*/
}
An interrupt handler for a device will be registered during autoconf(9)
with a call to the above intr_establish().
The main external interrupt handler, which handles all system interrupts,
will select the appropriate handler for the device that created the
interrupt when an interrupt is generated. In this case, the handler is
the routine assigned to ih_fun, and evcount will be made aware of
interrupt occurrence.
SEE ALSOsystat(1), queue(3), sysctl(3), intro(4), vmstat(8), autoconf(9)AUTHORS
The evcount API was written by Artur Grabowski and Aaron Campbell for
OpenBSD 3.6.
OpenBSD 4.9 September 20, 2010 OpenBSD 4.9