Rx: Build rxperf test application on Windows
[openafs.git] / src / rx / rx_trace.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13
14 #ifndef RXDEBUG
15 char rxi_tracename[80] = "\0Tracing not compiled in";
16 #ifdef DUMPTRACE
17 int
18 main(int argc, char **argv)
19 {
20     return 0;
21 }
22 #endif
23 #else
24 #include <string.h>
25 #ifdef AFS_NT40_ENV
26 #include <fcntl.h>
27 #include <io.h>
28 #else
29 #include <sys/file.h>
30 #include <unistd.h>
31 #endif
32 #include "rx.h"
33 #include "rx_globals.h"
34 #include "rx_trace.h"
35
36 #ifdef RXTRACEON
37 char rxi_tracename[80] = "/tmp/rxcalltrace";
38 #else
39 char rxi_tracename[80] =
40     "\0Change This pathname (and preceding NUL) to initiate tracing";
41 #endif
42 int rxi_logfd = -1;
43 char rxi_tracebuf[4096];
44 afs_uint32 rxi_tracepos = 0;
45
46 struct rx_trace {
47     afs_uint32 cid;
48     unsigned short call;
49     unsigned short qlen;
50     afs_uint32 now;
51     afs_uint32 waittime;
52     afs_uint32 servicetime;
53     afs_uint32 event;
54 };
55
56 void
57 rxi_flushtrace(void)
58 {
59     if (rxi_logfd >= 0)
60         write(rxi_logfd, rxi_tracebuf, rxi_tracepos);
61     rxi_tracepos = 0;
62 }
63
64 void
65 rxi_calltrace(unsigned int event, struct rx_call *call)
66 {
67     struct clock now;
68     struct rx_trace rxtinfo;
69
70     if (!rxi_tracename[0])
71         return;
72
73     if (rxi_logfd < 0) {
74         rxi_logfd = open(rxi_tracename, O_WRONLY | O_CREAT | O_TRUNC, 0777);
75         if (rxi_logfd < 0)
76             rxi_tracename[0] = '\0';
77     }
78     clock_GetTime(&now);
79
80     rxtinfo.event = event;
81     rxtinfo.now = now.sec * 1000 + now.usec / 1000;
82     rxtinfo.cid = call->conn->cid;
83     rxtinfo.call = *(call->callNumber);
84     rxtinfo.qlen = rx_nWaiting;
85     rxtinfo.servicetime = 0;
86     rxtinfo.waittime = 0;
87
88     switch (event) {
89     case RX_CALL_END:
90         clock_Sub(&now, &(call->traceStart));
91         rxtinfo.servicetime = now.sec * 10000 + now.usec / 100;
92         if (call->traceWait.sec) {
93             now = call->traceStart;
94             clock_Sub(&now, &(call->traceWait));
95             rxtinfo.waittime = now.sec * 10000 + now.usec / 100;
96         } else
97             rxtinfo.waittime = 0;
98         call->traceWait.sec = call->traceWait.usec = call->traceStart.sec =
99             call->traceStart.usec = 0;
100         break;
101
102     case RX_CALL_START:
103         call->traceStart = now;
104         if (call->traceWait.sec) {
105             clock_Sub(&now, &(call->traceWait));
106             rxtinfo.waittime = now.sec * 10000 + now.usec / 100;
107         } else
108             rxtinfo.waittime = 0;
109         break;
110
111     case RX_TRACE_DROP:
112         if (call->traceWait.sec) {
113             clock_Sub(&now, &(call->traceWait));
114             rxtinfo.waittime = now.sec * 10000 + now.usec / 100;
115         } else
116             rxtinfo.waittime = 0;
117         break;
118
119     case RX_CALL_ARRIVAL:
120         call->traceWait = now;
121     default:
122         break;
123     }
124
125     memcpy(rxi_tracebuf + rxi_tracepos, &rxtinfo, sizeof(struct rx_trace));
126     rxi_tracepos += sizeof(struct rx_trace);
127     if (rxi_tracepos >= (4096 - sizeof(struct rx_trace)))
128         rxi_flushtrace();
129 }
130
131 #ifdef DUMPTRACE
132 #include <errno.h>
133 #ifdef AFS_NT40_ENV
134 #include <afs/afsutil.h>
135 #endif
136
137 int
138 main(int argc, char **argv)
139 {
140     struct rx_trace ip;
141     int err = 0;
142
143     setlinebuf(stdout);
144     argv++;
145     argc--;
146     while (argc && **argv == '-') {
147         if (strcmp(*argv, "-trace") == 0) {
148             strcpy(rxi_tracename, *(++argv));
149             argc--;
150         } else {
151             err++;
152             break;
153         }
154         argv++, argc--;
155     }
156     if (err || argc != 0) {
157         printf("usage: dumptrace [-trace pathname]");
158         exit(1);
159     }
160
161     rxi_logfd = open(rxi_tracename, O_RDONLY);
162     if (rxi_logfd < 0) {
163         perror("");
164         exit(errno);
165     }
166
167     while (read(rxi_logfd, &ip, sizeof(struct rx_trace))) {
168         printf("%9u ", ip.now);
169         switch (ip.event) {
170         case RX_CALL_END:
171             putchar('E');
172             break;
173         case RX_CALL_START:
174             putchar('S');
175             break;
176         case RX_CALL_ARRIVAL:
177             putchar('A');
178             break;
179         case RX_TRACE_DROP:
180             putchar('D');
181             break;
182         default:
183             putchar('U');
184             break;
185         }
186         printf(" %3u %7u %7u      %x.%x\n", ip.qlen, ip.servicetime,
187                ip.waittime, ip.cid, ip.call);
188     }
189     return 0;
190 }
191
192 #endif /* DUMPTRACE */
193 #endif /* RXDEBUG */