dux-rxk-init-is-void-20040808
[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 RCSID
14     ("$Header$");
15
16 #ifdef RXDEBUG
17 #ifdef HAVE_STRING_H
18 #include <string.h>
19 #else
20 #ifdef HAVE_STRINGS_H
21 #include <strings.h>
22 #endif
23 #endif
24 #ifdef AFS_NT40_ENV
25 #include <fcntl.h>
26 #include <io.h>
27 #else
28 #include <sys/file.h>
29 #include <unistd.h>
30 #endif
31 #include "rx.h"
32 #include "rx_globals.h"
33 #include "rx_trace.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()
57 {
58     if (rxi_logfd >= 0)
59         write(rxi_logfd, rxi_tracebuf, rxi_tracepos);
60     rxi_tracepos = 0;
61 }
62
63 void
64 rxi_calltrace(event, call)
65      unsigned int event;
66      struct rx_call *call;
67 {
68     struct clock now;
69     struct rx_trace rxtinfo;
70
71     if (!rxi_tracename[0])
72         return;
73
74     if (rxi_logfd < 0) {
75         rxi_logfd = open(rxi_tracename, O_WRONLY | O_CREAT | O_TRUNC, 0777);
76         if (rxi_logfd < 0)
77             rxi_tracename[0] = '\0';
78     }
79     clock_GetTime(&now);
80
81     rxtinfo.event = event;
82     rxtinfo.now = now.sec * 1000 + now.usec / 1000;
83     rxtinfo.cid = call->conn->cid;
84     rxtinfo.call = *(call->callNumber);
85     rxtinfo.qlen = rx_nWaiting;
86     rxtinfo.servicetime = 0;
87     rxtinfo.waittime = 0;
88
89     switch (event) {
90     case RX_CALL_END:
91         clock_Sub(&now, &(call->traceStart));
92         rxtinfo.servicetime = now.sec * 10000 + now.usec / 100;
93         if (call->traceWait.sec) {
94             now = call->traceStart;
95             clock_Sub(&now, &(call->traceWait));
96             rxtinfo.waittime = now.sec * 10000 + now.usec / 100;
97         } else
98             rxtinfo.waittime = 0;
99         call->traceWait.sec = call->traceWait.usec = call->traceStart.sec =
100             call->traceStart.usec = 0;
101         break;
102
103     case RX_CALL_START:
104         call->traceStart = now;
105         if (call->traceWait.sec) {
106             clock_Sub(&now, &(call->traceWait));
107             rxtinfo.waittime = now.sec * 10000 + now.usec / 100;
108         } else
109             rxtinfo.waittime = 0;
110         break;
111
112     case RX_TRACE_DROP:
113         if (call->traceWait.sec) {
114             clock_Sub(&now, &(call->traceWait));
115             rxtinfo.waittime = now.sec * 10000 + now.usec / 100;
116         } else
117             rxtinfo.waittime = 0;
118         break;
119
120     case RX_CALL_ARRIVAL:
121         call->traceWait = now;
122     default:
123         break;
124     }
125
126     memcpy(rxi_tracebuf + rxi_tracepos, &rxtinfo, sizeof(struct rx_trace));
127     rxi_tracepos += sizeof(struct rx_trace);
128     if (rxi_tracepos >= (4096 - sizeof(struct rx_trace)))
129         rxi_flushtrace();
130 }
131
132 #ifdef DUMPTRACE
133 #include <errno.h>
134 #ifdef AFS_NT40_ENV
135 #include <afs/afsutil.h>
136 #endif
137
138 int
139 main(argc, argv)
140      char **argv;
141 {
142     struct rx_trace ip;
143     int err = 0;
144
145     setlinebuf(stdout);
146     argv++;
147     argc--;
148     while (argc && **argv == '-') {
149         if (strcmp(*argv, "-trace") == 0) {
150             strcpy(rxi_tracename, *(++argv));
151             argc--;
152         } else {
153             err++;
154             break;
155         }
156         argv++, argc--;
157     }
158     if (err || argc != 0) {
159         printf("usage: dumptrace [-trace pathname]");
160         exit(1);
161     }
162
163     rxi_logfd = open(rxi_tracename, O_RDONLY);
164     if (rxi_logfd < 0) {
165         perror("");
166         exit(errno);
167     }
168
169     while (read(rxi_logfd, &ip, sizeof(struct rx_trace))) {
170         printf("%9u ", ip.now);
171         switch (ip.event) {
172         case RX_CALL_END:
173             putchar('E');
174             break;
175         case RX_CALL_START:
176             putchar('S');
177             break;
178         case RX_CALL_ARRIVAL:
179             putchar('A');
180             break;
181         case RX_TRACE_DROP:
182             putchar('D');
183             break;
184         default:
185             putchar('U');
186             break;
187         }
188         printf(" %3u %7u %7u      %x.%x\n", ip.qlen, ip.servicetime,
189                ip.waittime, ip.cid, ip.call);
190     }
191 }
192
193 #endif /* DUMPTRACE */
194
195 #endif