Subject: interrupt stats on i386
To: None <port-i386@NetBSD.ORG>
From: John M Vinopal <banshee@gabriella.resort.com>
List: port-i386
Date: 04/04/1996 02:24:17
I hacked together a little something that delves into the dark
heart of i386; its not vmstat -i, but coupled with dmesg, its something.
/* Hackedover vmstat -i for i386
* Thu Apr 4 02:23:55 PST 1996
* banshee@resort.com
*/
#include <err.h>
#include <fcntl.h>
#include <kvm.h>
#include <limits.h>
#include <nlist.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/* Extracted from isamachdep.[c,h] */
#define ICU_LEN 16
struct intrhand {
int (*ih_fun)();
void *ih_arg;
u_long ih_count;
struct intrhand *ih_next;
int ih_level;
int ih_irq;
};
struct intrhand *cur[ICU_LEN];
static struct nlist namelist[] = {
#define X_INTRHAND 0
{ "_intrhand" }, /* Interrupt handler */
{ NULL },
};
static kvm_t *kd = NULL;
char *nlistf = NULL;
char *memf = NULL;
#define KVM_ERROR(_string) { \
warnx((_string)); \
errx(1, kvm_geterr(kd)); \
}
/*
* Dereference the namelist pointer `v' and fill in the local copy
* 'p' which is of size 's'.
*/
#define deref_nl(v, p, s) deref_kptr((void *)namelist[(v)].n_value, (p), (s));
static void deref_kptr __P(( void *, void *, size_t));
/*
* Dereference the kernel pointer `kptr' and fill in the local copy
* pointed to by `ptr'. The storage space must be pre-allocated,
* and the size of the copy passed in `len'.
*/
static void
deref_kptr(kptr, ptr, len)
void *kptr, *ptr;
size_t len;
{
char buf[128];
if (kvm_read(kd, (u_long)kptr, (char *)ptr, len) != len) {
bzero(buf, sizeof(buf));
snprintf(buf, (sizeof(buf) - 1),
"can't dereference kptr 0x%x", (uint)kptr);
KVM_ERROR(buf);
}
}
int
main()
{
char errbuf[_POSIX2_LINE_MAX];
int i, irq;
/* Open the kernel. */
if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf)) == NULL)
errx(1, "kvm_openfiles: %s", errbuf);
/* Obtain the namelist symbols from the kernel. */
if (kvm_nlist(kd, namelist))
KVM_ERROR("kvm_nlist failed to read symbols.");
deref_nl(X_INTRHAND, &cur, sizeof(struct intrhand) * ICU_LEN);
printf("IRQ COUNT\n");
for (irq = 0; irq < ICU_LEN; irq++) {
struct intrhand *q, tmp;
q = cur[irq];
while (q) {
deref_kptr(q, &tmp, sizeof(struct intrhand));
printf("%3d %5lu\n", tmp.ih_irq, tmp.ih_count);
q = tmp.ih_next;
}
}
}