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