~kris/9p

9hist

ref: 8d56d8a01106a05f1530797fef6a907dc41e3fc4 9hist/port/devintrts.c -rw-r--r-- 2.0 KiB
8d56d8a0 — David du Colombier Plan 9 from Bell Labs 2000-04-25 26 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 */
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"

enum {
	Qdir,
	Qintrts,
};

static Dirtab intrtsdir[] = {
	"intrts",	{ Qintrts, 0 },		0,	0666,
};

void (*saveintrts)(void) = nil;

/* interrupt timestamps, trap() fills intrts each interrupt */
uvlong	intrts;
static	struct {
	Lock;
	int	vno;		/* vector to save timestamps for */
	int	n;		/* number of valid timestamps in ts[] */
	uvlong	ts[128];	/* time stamps */
} tsalloc;

/* called with interrupts off by interrupt routine */
void
_saveintrts(void)
{
	ilock(&tsalloc);
	if(tsalloc.n < nelem(tsalloc.ts))
		tsalloc.ts[tsalloc.n++] = m->intrts;
	iunlock(&tsalloc);
}

/* read interrupt timestamps */
static long
readintrts(void *buf, int n)
{
	n /= sizeof(uvlong);
	if(n <= 0)
		return 0;
	ilock(&tsalloc);
	if(n > tsalloc.n)
		n = tsalloc.n;
	memmove(buf, tsalloc.ts, n*sizeof(uvlong));
	tsalloc.n = 0;
	iunlock(&tsalloc);
	return n*sizeof(uvlong);
}


static void
intrtsreset(void)
{
	saveintrts = _saveintrts;
}

static Chan*
intrtsattach(char* spec)
{
	return devattach('Z', spec);	/* everything good was taken */
}

int
intrtswalk(Chan* c, char* name)
{
	return devwalk(c, name, intrtsdir, nelem(intrtsdir), devgen);
}

static void
intrtsstat(Chan* c, char* dp)
{
	devstat(c, dp, intrtsdir, nelem(intrtsdir), devgen);
}

static Chan*
intrtsopen(Chan* c, int omode)
{
	return devopen(c, omode, intrtsdir, nelem(intrtsdir), devgen);
}

static void
intrtsclose(Chan*)
{
}

static long
intrtsread(Chan* c, void* a, long n, vlong)
{
	switch(c->qid.path & ~CHDIR){

	case Qdir:
		return devdirread(c, a, n, intrtsdir, nelem(intrtsdir), devgen);

	case Qintrts:
		return readintrts(a, n);
	}

	error(Eperm);
	return 0;
}

static long
intrtswrite(Chan*, void*, long, vlong)
{
	error(Eperm);
	return 0;
}

Dev intrtsdevtab = {
	'Z',
	"intrts",

	intrtsreset,
	devinit,
	intrtsattach,
	devclone,
	intrtswalk,
	intrtsstat,
	intrtsopen,
	devcreate,
	intrtsclose,
	intrtsread,
	devbread,
	intrtswrite,
	devbwrite,
	devremove,
	devwstat,
};