]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/dtracy/dtracy.c
aux/realemu: run cpuproc in same fd group as fileserver
[plan9front.git] / sys / src / cmd / dtracy / dtracy.c
1 #include <u.h>
2 #include <libc.h>
3 #include <dtracy.h>
4 #include <bio.h>
5 #include "dat.h"
6 #include "fns.h"
7
8 DTAgg noagg;
9
10 char *dtracyroot = "#Δ";
11 int dtracyno;
12 int ctlfd, buffd;
13
14 int
15 min(int a, int b)
16 {
17         return a < b ? a : b;
18 }
19
20 int
21 max(int a, int b)
22 {
23         return a < b ? b : a;
24 }
25
26 void *
27 emalloc(ulong n)
28 {
29         void *v;
30         
31         v = malloc(n);
32         if(v == nil) sysfatal("malloc: %r");
33         memset(v, 0, n);
34         setmalloctag(v, getcallerpc(&n));
35         return v;
36 }
37
38 void *
39 erealloc(void *v, ulong n)
40 {
41         v = realloc(v, n);
42         if(n != 0){
43                 if(v == nil) sysfatal("realloc: %r");
44                 setrealloctag(v, getcallerpc(&v));
45         }
46         return v;
47 }
48
49 void *
50 dtmalloc(ulong n)
51 {
52         return emalloc(n);
53 }
54
55 void
56 dtfree(void *v)
57 {
58         free(v);
59 }
60
61 void
62 defvar(char *name, int idx, Type *ty)
63 {
64         Symbol *s;
65         
66         s = getsym(name);
67         s->type = SYMVAR;
68         s->idx = idx;
69         s->typ = ty;
70 }
71
72 void
73 globvars(void)
74 {
75         defvar("arg0", DTV_ARG0, type(TYPINT, 8, 1));
76         defvar("arg1", DTV_ARG1, type(TYPINT, 8, 1));
77         defvar("arg2", DTV_ARG2, type(TYPINT, 8, 1));
78         defvar("arg3", DTV_ARG3, type(TYPINT, 8, 1));
79         defvar("arg4", DTV_ARG4, type(TYPINT, 8, 1));
80         defvar("arg5", DTV_ARG5, type(TYPINT, 8, 1));
81         defvar("arg6", DTV_ARG6, type(TYPINT, 8, 1));
82         defvar("arg7", DTV_ARG7, type(TYPINT, 8, 1));
83         defvar("arg8", DTV_ARG8, type(TYPINT, 8, 1));
84         defvar("arg9", DTV_ARG9, type(TYPINT, 8, 1));
85         defvar("pid", DTV_PID, type(TYPINT, 4, 1));
86         defvar("machno", DTV_MACHNO, type(TYPINT, 4, 1));
87         defvar("time", DTV_TIME, type(TYPINT, 8, 0));
88         defvar("probe", DTV_PROBE, type(TYPSTRING));
89 }
90
91 int
92 setup(void)
93 {
94         char buf[512];
95         char *p;
96         int n;
97         
98         snprint(buf, sizeof(buf), "%s/clone", dtracyroot);
99         ctlfd = open(buf, ORDWR);
100         if(ctlfd < 0) return -1;
101         n = read(ctlfd, buf, sizeof(buf) - 1);
102         if(n < 0) return -1;
103         buf[n] = 0;
104         dtracyno = strtol(buf, &p, 10);
105         if(p == buf || *p != 0){
106                 werrstr("expected number reading from ctl");
107                 return -1;
108         }
109         snprint(buf, sizeof(buf), "%s/%d/buf", dtracyroot, dtracyno);
110         buffd = open(buf, OREAD);
111         if(buffd < 0) return -1;
112         return 0;
113 }
114
115 int
116 progcopy(void)
117 {
118         char buf[512];
119         int fd;
120         char *prog;
121         Fmt f;
122
123         fmtstrinit(&f);
124         packclauses(&f);
125         prog = fmtstrflush(&f);
126         snprint(buf, sizeof(buf), "%s/%d/prog", dtracyroot, dtracyno);
127         fd = open(buf, OWRITE);
128         if(fd < 0) return -1;
129         if(write(fd, prog, strlen(prog)) < 0){
130                 close(fd);
131                 return -1;
132         }
133         close(fd);
134         return 0;
135 }
136
137 int
138 epidread(void)
139 {
140         char buf[512];
141         Biobuf *bp;
142         char *s;
143         char *f[5];
144         int a, b, c;
145
146         snprint(buf, sizeof(buf), "%s/%d/epid", dtracyroot, dtracyno);
147         bp = Bopen(buf, OREAD);
148         if(bp == nil) return -1;
149         for(; s = Brdstr(bp, '\n', 1), s != nil; free(s)){
150                 if(tokenize(s, f, nelem(f)) != 4)
151                         goto err;
152                 a = atoi(f[0]);
153                 b = atoi(f[1]);
154                 c = atoi(f[2]);
155                 addepid(a, b, c, f[3]);
156         }
157         return 0;
158 err:
159         werrstr("epidread: invalid format");
160         free(s);
161         return -1;
162         
163 }
164
165 int
166 bufread(Biobuf *bp)
167 {
168         static uchar buf[65536];
169         int n;
170         
171         n = read(buffd, buf, sizeof(buf));
172         if(n < 0)
173                 sysfatal("bufread: %r");
174         if(parsebuf(buf, n, bp) < 0)
175                 sysfatal("parsebuf: %r");
176         Bflush(bp);
177         return 0;
178 }
179
180 void
181 aggproc(void)
182 {
183         char buf[65536];
184         int buffd, n;
185         extern int interrupted;
186
187         switch(rfork(RFPROC|RFMEM)){
188         case -1: sysfatal("rfork: %r");
189         case 0: return;
190         default: break;
191         }
192         snprint(buf, sizeof(buf), "%s/%d/aggbuf", dtracyroot, dtracyno);
193         buffd = open(buf, OREAD);
194         if(buffd < 0) sysfatal("open: %r");
195         agginit();
196         atnotify(aggnote, 1);
197         while(!interrupted){
198                 n = read(buffd, buf, sizeof(buf));
199                 if(n < 0){
200                         if(interrupted)
201                                 break;
202                         sysfatal("aggbufread: %r");
203                 }
204                 if(aggparsebuf((uchar *) buf, n) < 0)
205                         exits("error");
206         }
207         aggdump();
208         exits(nil);
209 }
210
211 static void
212 usage(void)
213 {
214         fprint(2, "usage: %s [ -d ] script\n", argv0);
215         exits("usage");
216 }
217
218 int dflag;
219
220 void
221 main(int argc, char **argv)
222 {
223         Biobuf *out;
224
225         dflag = 0;
226         ARGBEGIN {
227         case 'd': dflag = 1; break;
228         default: usage();
229         } ARGEND;
230         if(argc != 1) usage();
231
232         fmtinstall(L'α', nodetfmt);
233         fmtinstall('t', typetfmt);
234         fmtinstall(L'I', dtefmt);
235         fmtinstall(L'τ', typefmt);
236         fmtinstall(L'ε', nodefmt);
237         lexinit();
238         lexstring(argv[0]);
239         globvars();
240         yyparse();
241         if(errors != 0)
242                 exits("errors");
243         if(dflag)
244                 dump();
245         else{
246                 if(setup() < 0)
247                         sysfatal("setup: %r");
248                 if(progcopy() < 0)
249                         sysfatal("progcopy: %r");
250                 if(epidread() < 0)
251                         sysfatal("epidread: %r");
252                 fprint(ctlfd, "go");
253                 out = Bfdopen(1, OWRITE);
254                 if(out == nil) sysfatal("Bfdopen: %r");
255                 if(aggid > 0)
256                         aggproc();
257                 for(;;)
258                         bufread(out);
259         }
260         exits(nil);
261 }