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