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