Import Upstream version 1.8.5
[hcoop/debian/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 #include <roken.h>
14
15 #ifndef RXDEBUG
16 char rxi_tracename[80] = "\0Tracing not compiled in";
17 #ifdef DUMPTRACE
18 int
19 main(int argc, char **argv)
20 {
21 return 0;
22 }
23 #endif
24 #else
25
26 #include "rx.h"
27 #include "rx_atomic.h"
28 #include "rx_globals.h"
29 #include "rx_internal.h"
30 #include "rx_trace.h"
31
32 #include "rx_conn.h"
33 #include "rx_call.h"
34
35 #ifdef RXTRACEON
36 char rxi_tracename[80] = "/tmp/rxcalltrace";
37 #else
38 char rxi_tracename[80] =
39 "\0Change This pathname (and preceding NUL) to initiate tracing";
40 #endif
41 int rxi_logfd = -1;
42 char rxi_tracebuf[4096];
43 afs_uint32 rxi_tracepos = 0;
44
45 struct rx_trace {
46 afs_uint32 cid;
47 unsigned short call;
48 unsigned short qlen;
49 afs_uint32 now;
50 afs_uint32 waittime;
51 afs_uint32 servicetime;
52 afs_uint32 event;
53 };
54
55 void
56 rxi_flushtrace(void)
57 {
58 afs_uint32 len = rxi_tracepos;
59
60 rxi_tracepos = 0;
61 if (rxi_logfd < 0)
62 return;
63 if (write(rxi_logfd, rxi_tracebuf, len) < 0) {
64 /* don't care */
65 }
66 }
67
68 void
69 rxi_calltrace(unsigned int event, struct rx_call *call)
70 {
71 struct clock now;
72 struct rx_trace rxtinfo;
73
74 if (!rxi_tracename[0])
75 return;
76
77 if (rxi_logfd < 0) {
78 rxi_logfd = open(rxi_tracename, O_WRONLY | O_CREAT | O_TRUNC, 0777);
79 if (rxi_logfd < 0)
80 rxi_tracename[0] = '\0';
81 }
82 clock_GetTime(&now);
83
84 rxtinfo.event = event;
85 rxtinfo.now = now.sec * 1000 + now.usec / 1000;
86 rxtinfo.cid = call->conn->cid;
87 rxtinfo.call = *(call->callNumber);
88 rxtinfo.qlen = rx_atomic_read(&rx_nWaiting);
89 rxtinfo.servicetime = 0;
90 rxtinfo.waittime = 0;
91
92 switch (event) {
93 case RX_CALL_END:
94 clock_Sub(&now, &(call->traceStart));
95 rxtinfo.servicetime = now.sec * 10000 + now.usec / 100;
96 if (call->traceWait.sec) {
97 now = call->traceStart;
98 clock_Sub(&now, &(call->traceWait));
99 rxtinfo.waittime = now.sec * 10000 + now.usec / 100;
100 } else
101 rxtinfo.waittime = 0;
102 call->traceWait.sec = call->traceWait.usec = call->traceStart.sec =
103 call->traceStart.usec = 0;
104 break;
105
106 case RX_CALL_START:
107 call->traceStart = now;
108 if (call->traceWait.sec) {
109 clock_Sub(&now, &(call->traceWait));
110 rxtinfo.waittime = now.sec * 10000 + now.usec / 100;
111 } else
112 rxtinfo.waittime = 0;
113 break;
114
115 case RX_TRACE_DROP:
116 if (call->traceWait.sec) {
117 clock_Sub(&now, &(call->traceWait));
118 rxtinfo.waittime = now.sec * 10000 + now.usec / 100;
119 } else
120 rxtinfo.waittime = 0;
121 break;
122
123 case RX_CALL_ARRIVAL:
124 call->traceWait = now;
125 default:
126 break;
127 }
128
129 memcpy(rxi_tracebuf + rxi_tracepos, &rxtinfo, sizeof(struct rx_trace));
130 rxi_tracepos += sizeof(struct rx_trace);
131 if (rxi_tracepos >= (4096 - sizeof(struct rx_trace)))
132 rxi_flushtrace();
133 }
134
135 #ifdef DUMPTRACE
136 #ifdef AFS_NT40_ENV
137 #include <afs/afsutil.h>
138 #endif
139
140 int
141 main(int argc, char **argv)
142 {
143 struct rx_trace ip;
144 int err = 0;
145
146 setlinebuf(stdout);
147 argv++;
148 argc--;
149 while (argc && **argv == '-') {
150 if (strcmp(*argv, "-trace") == 0) {
151 strcpy(rxi_tracename, *(++argv));
152 argc--;
153 } else {
154 err++;
155 break;
156 }
157 argv++, argc--;
158 }
159 if (err || argc != 0) {
160 printf("usage: dumptrace [-trace pathname]");
161 exit(1);
162 }
163
164 rxi_logfd = open(rxi_tracename, O_RDONLY);
165 if (rxi_logfd < 0) {
166 perror("");
167 exit(errno);
168 }
169
170 while (read(rxi_logfd, &ip, sizeof(struct rx_trace))) {
171 printf("%9u ", ip.now);
172 switch (ip.event) {
173 case RX_CALL_END:
174 putchar('E');
175 break;
176 case RX_CALL_START:
177 putchar('S');
178 break;
179 case RX_CALL_ARRIVAL:
180 putchar('A');
181 break;
182 case RX_TRACE_DROP:
183 putchar('D');
184 break;
185 default:
186 putchar('U');
187 break;
188 }
189 printf(" %3u %7u %7u %x.%x\n", ip.qlen, ip.servicetime,
190 ip.waittime, ip.cid, ip.call);
191 }
192 return 0;
193 }
194
195 #endif /* DUMPTRACE */
196 #endif /* RXDEBUG */