removed unnecessary include files
[dyninst.git] / rtinst / src / RTcm5_pn.c
1 /*
2  * This file contains the implementation of runtime dynamic instrumentation
3  *   functions for a TMC CM-5 machine.
4  *
5  *
6  * $Log: RTcm5_pn.c,v $
7  * Revision 1.2  1993/07/02 21:53:33  hollings
8  * removed unnecessary include files
9  *
10  * Revision 1.1  1993/07/02  21:49:35  hollings
11  * Initial revision
12  *
13  *
14  */
15 #include <signal.h>
16 #include <assert.h>
17 #include "rtinst.h"
18 #include "trace.h"
19 #include "traceio.h"
20
21 #include <cm/cmmd/amx.h>
22 #include <cm/cmmd/mp.h>
23 #include <cm/cmmd/cn.h>
24 #include <cm/cmmd/io.h>
25 #include <cm/cmmd/util.h>
26 #include <cm/cmmd/cmmd_constants.h>
27 #include <cm/cmmd.h>
28 #include <cm/cmna.h>
29
30 #include <stdio.h>
31 #include <string.h>
32 #include <sys/types.h>
33 #include <sys/stdtypes.h>
34 #include <sys/time.h>
35 #include <sys/timeb.h>
36 #include <dirent.h>
37 #include <sys/stat.h>
38 #include <sys/vfs.h>
39 #include <cm/cm_file.h>
40 #include <cm/cm_errno.h>
41 #include <errno.h>
42 #include <sys/un.h>
43 #include <sys/socket.h>
44 #include <netdb.h>
45 #include <netinet/in.h>
46 #include <fcntl.h>
47 #include <sys/filio.h>
48 #include <math.h>
49
50 #define NI_CLK_USEC 33
51 #define MILLION 1000000
52
53 void DYNINSTstartWallTimer(tTimer *timer)
54 {
55     if (timer->trigger && (!timer->trigger->value)) return;
56     if (timer->counter == 0) {
57          CMOS_get_time(&timer->start);
58          timer->normalize = NI_CLK_USEC * MILLION;
59     }
60     /* this must be last to prevent race conditions with the sampler */
61     timer->counter++;
62 }
63
64 void DYNINSTstopWallTimer(tTimer *timer)
65 {
66     time64 end;
67
68     if (timer->trigger && (timer->trigger->value <= 0)) return;
69     if (!timer->counter) return;
70
71     if (timer->counter == 1) {
72          CMOS_get_time(&end);
73          timer->total += (end - timer->start);
74     }
75     /* this must be last to prevent race conditions with the sampler */
76     timer->counter--;
77 }
78
79
80 void DYNINSTstartProcessTimer(tTimer *timer)
81 {
82     if (timer->trigger && (!timer->trigger->value)) return;
83     if (timer->counter == 0) {
84          CMOS_get_time(&timer->start);
85          CMOS_get_NI_time(&timer->ni_start);
86          timer->normalize = NI_CLK_USEC * MILLION;
87     }
88     /* this must be last to prevent race conditions with the sampler */
89     timer->counter++;
90 }
91
92 void DYNINSTstopProcessTimer(tTimer *timer)
93 {
94     time64 end;
95     time64 ni_end;
96
97     if (timer->trigger && (timer->trigger->value <= 0)) return;
98     if (!timer->counter) return;
99
100     if (timer->counter == 1) {
101          CMOS_get_time(&end);
102          CMOS_get_NI_time(&ni_end);
103          timer->total += (end - timer->start);
104          timer->total -= (ni_end - timer->ni_start);
105          if (timer->total < 0) abort();
106     }
107     /* this must be last to prevent race conditions with the sampler */
108     timer->counter--;
109 }
110
111 void DYNINSTreportTimer(tTimer *timer)
112 {
113     time64 now;
114     double value;
115     time64 total;
116     time64 ni_now;
117     traceSample sample;
118
119
120     total = timer->total;
121     if (timer->counter) {
122         /* timer is running */
123
124         CMOS_get_time(&now);
125         CMOS_get_NI_time(&ni_now);
126         if (timer->type == processTime) {
127             total += (now - ni_now) - (timer->start - timer->ni_start);
128         } else {
129             total += (now - timer->start);
130         }
131     }
132     if (total < 0) {
133         double w1, w2, ni1, ni2;
134
135         w1 = timer->start;
136         w2 = now;
137         ni1 = timer->ni_start;
138         ni2 = ni_now;
139         abort();
140     }
141
142     sample.value = total / (double) timer->normalize;
143     sample.id = timer->id;
144
145     DYNINSTgenerateTraceRecord(0, TR_SAMPLE, sizeof(sample), &sample);
146 }
147
148 time64 startWall;
149 int DYNINSTnoHandlers;
150
151 /*
152  * should be called before main in each process1.
153  *
154  */
155 void DYNINSTinit()
156 {
157     char *interval;
158     struct timeval tv;
159     time64 startNItime;
160     extern void DYNINSTalarmExpire();
161
162     CMOS_get_time(&startNItime);
163     gettimeofday(&tv, NULL);
164
165     startWall = tv.tv_sec;
166     startWall *= MILLION;
167     startWall += tv.tv_usec;
168
169     /* change time base to ni time */
170     startWall *= NI_CLK_USEC;
171
172     startWall -= startNItime;
173
174     initTraceLibPN();
175 }
176
177 void DYNINSTexit()
178 {
179     cleanupTraceLibPN();
180 }
181
182 /*
183  * generate a trace record onto the named stream.
184  *
185  */
186 void DYNINSTgenerateTraceRecord(traceStream sid, short type, short length,
187     void *eventData)
188 {
189     int ret;
190     int count;
191     time64 pTime;
192     double newVal;
193     char buffer[1024];
194     traceSample *sample;
195     traceHeader header;
196
197     /* check and see if we should aggregate to other nodes */
198     if ((type == TR_SAMPLE) && (((traceSample*) eventData)->id.aggregate)) {
199          /* not ready yet! */
200          abort();
201
202          /* use reduction net to compute aggregate */
203          sample = (traceSample*) eventData;
204          /* newVal = CMMD_reduce_float(sample->value, CMMD_combiner_fadd); */
205          newVal = CMCN_reduce_float(sample->value, CMMD_combiner_fadd);
206          sample->value = newVal;
207
208
209          /* only node zero reports value */
210          if (CMMD_self_address()) return;
211     }
212
213     CMOS_get_time(&header.wall);
214     header.wall += startWall;
215     header.wall /= NI_CLK_USEC;
216
217     CMOS_get_time(&header.process);
218     CMOS_get_NI_time(&pTime);
219     header.process -= pTime;
220     header.process /= NI_CLK_USEC;
221
222     header.type = type;
223     header.length = length;
224     count = 0;
225     memcpy(&buffer[count], &sid, sizeof(traceStream));
226     count += sizeof(traceStream);
227
228     memcpy(&buffer[count], &header, sizeof(header));
229     count += sizeof(header);
230
231     memcpy(&buffer[count], eventData, length);
232     count += length;
233
234     TRACE(buffer, count);
235 }
236
237 void DYNINSTbreakPoint(int arg)
238 {
239     /* printf("Break point %d reached\n", arg); */
240     asm("ta 0x81");
241 }