2 * This file contains the implementation of runtime dynamic instrumentation
3 * functions for a TMC CM-5 machine.
7 * Revision 1.2 1993/07/02 21:53:33 hollings
8 * removed unnecessary include files
10 * Revision 1.1 1993/07/02 21:49:35 hollings
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>
32 #include <sys/types.h>
33 #include <sys/stdtypes.h>
35 #include <sys/timeb.h>
39 #include <cm/cm_file.h>
40 #include <cm/cm_errno.h>
43 #include <sys/socket.h>
45 #include <netinet/in.h>
47 #include <sys/filio.h>
50 #define NI_CLK_USEC 33
51 #define MILLION 1000000
53 void DYNINSTstartWallTimer(tTimer *timer)
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;
60 /* this must be last to prevent race conditions with the sampler */
64 void DYNINSTstopWallTimer(tTimer *timer)
68 if (timer->trigger && (timer->trigger->value <= 0)) return;
69 if (!timer->counter) return;
71 if (timer->counter == 1) {
73 timer->total += (end - timer->start);
75 /* this must be last to prevent race conditions with the sampler */
80 void DYNINSTstartProcessTimer(tTimer *timer)
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;
88 /* this must be last to prevent race conditions with the sampler */
92 void DYNINSTstopProcessTimer(tTimer *timer)
97 if (timer->trigger && (timer->trigger->value <= 0)) return;
98 if (!timer->counter) return;
100 if (timer->counter == 1) {
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();
107 /* this must be last to prevent race conditions with the sampler */
111 void DYNINSTreportTimer(tTimer *timer)
120 total = timer->total;
121 if (timer->counter) {
122 /* timer is running */
125 CMOS_get_NI_time(&ni_now);
126 if (timer->type == processTime) {
127 total += (now - ni_now) - (timer->start - timer->ni_start);
129 total += (now - timer->start);
133 double w1, w2, ni1, ni2;
137 ni1 = timer->ni_start;
142 sample.value = total / (double) timer->normalize;
143 sample.id = timer->id;
145 DYNINSTgenerateTraceRecord(0, TR_SAMPLE, sizeof(sample), &sample);
149 int DYNINSTnoHandlers;
152 * should be called before main in each process1.
160 extern void DYNINSTalarmExpire();
162 CMOS_get_time(&startNItime);
163 gettimeofday(&tv, NULL);
165 startWall = tv.tv_sec;
166 startWall *= MILLION;
167 startWall += tv.tv_usec;
169 /* change time base to ni time */
170 startWall *= NI_CLK_USEC;
172 startWall -= startNItime;
183 * generate a trace record onto the named stream.
186 void DYNINSTgenerateTraceRecord(traceStream sid, short type, short length,
197 /* check and see if we should aggregate to other nodes */
198 if ((type == TR_SAMPLE) && (((traceSample*) eventData)->id.aggregate)) {
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;
209 /* only node zero reports value */
210 if (CMMD_self_address()) return;
213 CMOS_get_time(&header.wall);
214 header.wall += startWall;
215 header.wall /= NI_CLK_USEC;
217 CMOS_get_time(&header.process);
218 CMOS_get_NI_time(&pTime);
219 header.process -= pTime;
220 header.process /= NI_CLK_USEC;
223 header.length = length;
225 memcpy(&buffer[count], &sid, sizeof(traceStream));
226 count += sizeof(traceStream);
228 memcpy(&buffer[count], &header, sizeof(header));
229 count += sizeof(header);
231 memcpy(&buffer[count], eventData, length);
234 TRACE(buffer, count);
237 void DYNINSTbreakPoint(int arg)
239 /* printf("Break point %d reached\n", arg); */