|
|
1.1 root 1: #include "u.h"
2: #include "../port/lib.h"
3: #include "mem.h"
4: #include "dat.h"
5: #include "fns.h"
6: #include "../port/error.h"
7:
8: #include "devtab.h"
9:
10: #define LRES 3 /* log of PC resolution */
11: #define SZ 4 /* sizeof of count cell; well known as 4 */
12:
13: struct
14: {
15: int minpc;
16: int maxpc;
17: int nbuf;
18: int time;
19: ulong *buf;
20: }kprof;
21:
22: enum{
23: Kprofdirqid,
24: Kprofdataqid,
25: Kprofctlqid,
26: Nkproftab=Kprofctlqid,
27: Kprofmaxqid,
28: };
29: Dirtab kproftab[Nkproftab]={
30: "kpdata", {Kprofdataqid}, 0, 0600,
31: "kpctl", {Kprofctlqid}, 0, 0600,
32: };
33:
34: void kproftimer(ulong);
35:
36: void
37: kprofreset(void)
38: {
39: }
40:
41: void
42: kprofinit(void)
43: {
44: if(SZ != sizeof kprof.buf[0])
45: panic("kprof size");
46: }
47:
48: Chan *
49: kprofattach(char *spec)
50: {
51: ulong n;
52:
53: /* allocate when first used */
54: kprof.minpc = KTZERO;
55: kprof.maxpc = (ulong)etext;
56: kprof.nbuf = (kprof.maxpc-kprof.minpc) >> LRES;
57: n = kprof.nbuf*SZ;
58: if(kprof.buf == 0) {
59: kprof.buf = xalloc(n);
60: if(kprof.buf == 0)
61: error(Enomem);
62: }
63: kproftab[0].length = n;
64: return devattach('T', spec);
65: }
66: Chan *
67: kprofclone(Chan *c, Chan *nc)
68: {
69: return devclone(c, nc);
70: }
71:
72: int
73: kprofwalk(Chan *c, char *name)
74: {
75: return devwalk(c, name, kproftab, (long)Nkproftab, devgen);
76: }
77:
78: void
79: kprofstat(Chan *c, char *db)
80: {
81: devstat(c, db, kproftab, (long)Nkproftab, devgen);
82: }
83:
84: Chan *
85: kprofopen(Chan *c, int omode)
86: {
87: if(c->qid.path == CHDIR){
88: if(omode != OREAD)
89: error(Eperm);
90: }
91: c->mode = openmode(omode);
92: c->flag |= COPEN;
93: c->offset = 0;
94: return c;
95: }
96:
97: void
98: kprofcreate(Chan *c, char *name, int omode, ulong perm)
99: {
100: USED(c, name, omode, perm);
101: error(Eperm);
102: }
103:
104: void
105: kprofremove(Chan *c)
106: {
107: USED(c);
108: error(Eperm);
109: }
110:
111: void
112: kprofwstat(Chan *c, char *dp)
113: {
114: USED(c, dp);
115: error(Eperm);
116: }
117:
118: void
119: kprofclose(Chan *c)
120: {
121: USED(c);
122: }
123:
124: long
125: kprofread(Chan *c, void *va, long n, ulong offset)
126: {
127: ulong tabend;
128: ulong w, *bp;
129: uchar *a, *ea;
130:
131: switch(c->qid.path & ~CHDIR){
132: case Kprofdirqid:
133: return devdirread(c, va, n, kproftab, Nkproftab, devgen);
134:
135: case Kprofdataqid:
136: tabend = kprof.nbuf*SZ;
137: if(offset & (SZ-1))
138: error(Ebadarg);
139: if(offset >= tabend){
140: n = 0;
141: break;
142: }
143: if(offset+n > tabend)
144: n = tabend-offset;
145: n &= ~(SZ-1);
146: a = va;
147: ea = a + n;
148: bp = kprof.buf + offset/SZ;
149: while(a < ea){
150: w = *bp++;
151: *a++ = w>>24;
152: *a++ = w>>16;
153: *a++ = w>>8;
154: *a++ = w>>0;
155: }
156: break;
157:
158: default:
159: n = 0;
160: break;
161: }
162: return n;
163: }
164:
165: long
166: kprofwrite(Chan *c, char *a, long n, ulong offset)
167: {
168: USED(offset);
169:
170: switch((int)(c->qid.path&~CHDIR)){
171: case Kprofctlqid:
172: if(strncmp(a, "startclr", 8) == 0){
173: memset((char *)kprof.buf, 0, kprof.nbuf*SZ);
174: kprof.time = 1;
175: }else if(strncmp(a, "start", 5) == 0)
176: kprof.time = 1;
177: else if(strncmp(a, "stop", 4) == 0)
178: kprof.time = 0;
179: else
180: error(Ebadctl);
181: break;
182: default:
183: error(Ebadusefd);
184: }
185: return n;
186: }
187:
188: void
189: kproftimer(ulong pc)
190: {
191: extern void spldone(void);
192:
193: if(kprof.time == 0)
194: return;
195: /*
196: * if the pc is coming out of spllo or splx,
197: * use the pc saved when we went splhi.
198: */
199: if(pc>=(ulong)splx && pc<=(ulong)spldone)
200: pc = m->splpc;
201:
202: kprof.buf[0] += TK2MS(1);
203: if(kprof.minpc<=pc && pc<kprof.maxpc){
204: pc -= kprof.minpc;
205: pc >>= LRES;
206: kprof.buf[pc] += TK2MS(1);
207: }else
208: kprof.buf[1] += TK2MS(1);
209: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.