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