1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8
9 #include <dxconfig.h>
10
11
12
13 #include <sys/types.h>
14 #include <string.h>
15 #include <dx/dx.h>
16 #include <stdio.h>
17
18 #if defined(HAVE_UNISTD_H)
19 #include <unistd.h>
20 #endif
21 #if defined(HAVE_SYS_TIME_H)
22 #include <sys/time.h>
23 #endif
24 #if defined(HAVE_SYS_TIMES_H)
25 #include <sys/times.h>
26 #endif
27 #if defined(HAVE_SYS_PARAM_H)
28 #include <sys/param.h>
29 #endif
30 #if defined(HAVE_TIME_H)
31 #include <time.h>
32 #endif
33
34
35 #ifndef HZ
36 #define HZ 60
37 #endif
38
39 #define EVENTS 2000
40
41 static
42 struct ti {
43 int trace; /* whether to trace times or not */
44 struct _proc {
45 struct event { /* per event info: */
46 double user, sys, real; /* time of this event */
47 char label[16]; /* this event's label */
48 int id; /* processor on which it ran */
49 int global; /* whether it is global or local */
50 } events[EVENTS]; /* one per event */
51 int n; /* number of events this processor */
52 int printed; /* count for printing */
53 struct last { /* last printed event time */
54 double user, sys, real; /* user, system, real times */
55 } last; /* per processor */
56 } *procs; /* one per processor */
57 } *ti = NULL; /* ptr to struct in global memory */
58
59
60 void
DXTraceTime(int t)61 DXTraceTime(int t)
62 {
63 static int been_here;
64 if (!been_here) {
65 DXinitdx();
66 been_here = 1;
67 }
68 if (ti)
69 ti->trace = t;
70 }
71
72
73 /*
74 * Internal routine: get a time split, measured in
75 * seconds since the first time split
76 */
77
78 #if ibmpvs && !paxc
79 static void
_times_svs(double * user,double * sys,double * real)80 _times_svs(double *user, double *sys, double *real)
81 {
82 static struct tms tms0;
83 struct tms tms1;
84 static double time0;
85 double time1;
86 extern double double_time();
87 static int fast;
88
89 if (!time0) {
90 times(&tms0);
91 time0 = double_time();
92 fast = getenv("SLOW")? 0 : 1;
93 }
94 if (!fast && (user || sys))
95 times(&tms1);
96 time1 = double_time();
97 if (user)
98 *user = fast? 0 : (float)(tms1.tms_utime-tms0.tms_utime) / HZ;
99 if (sys)
100 *sys = fast? 0 : (float)(tms1.tms_stime-tms0.tms_stime) / HZ;
101 if (real)
102 *real = time1-time0;
103 }
104 #endif
105
106 #if defined(os2) || defined(intelnt) || defined(WIN32)
107
108 static void
_times_unix(double * user,double * sys,double * real)109 _times_unix(double *user, double *sys, double *real)
110 {
111 static clock_t time0 = 0;
112 static time_t rtime0 = 0;
113 clock_t time1;
114 time_t rtime1;
115 if (!time0)
116 {
117 time0 = clock();
118 rtime0 = time(0);
119 }
120 time1 = clock();
121 rtime1 = time(0);
122 if (user)
123 *user = (float)(time1) / CLOCKS_PER_SEC;
124 if (sys)
125 *sys = (float)(time1) / CLOCKS_PER_SEC;
126 if (real)
127 *real = (float)(rtime1-rtime0);
128 }
129
130 #else
131
132 static void
_times_unix(double * user,double * sys,double * real)133 _times_unix(double *user, double *sys, double *real)
134 {
135 static struct tms tms0;
136 struct tms tms1;
137 static int time0;
138 int time1;
139 if (!time0)
140 time0 = times(&tms0);
141 time1 = times(&tms1);
142 if (user)
143 *user = (float)(tms1.tms_utime/*-tms0.tms_utime*/) / HZ;
144 if (sys)
145 *sys = (float)(tms1.tms_stime/*-tms0.tms_stime*/) / HZ;
146 if (real)
147 *real = (float)(time1-time0) / HZ;
148
149 }
150 #endif
151
152 #if ibm6000 || sun4 || solaris
153 static void
_times_ibmsun4(double * user,double * sys,double * real)154 _times_ibmsun4(double *user, double *sys, double *real)
155 {
156 static struct tms tms0;
157 struct tms tms1;
158 struct timeval tp;
159 struct timezone tzp;
160 static double time0;
161 double time1;
162
163 if (!time0) {
164 times(&tms0);
165 gettimeofday(&tp, &tzp);
166 time0 = (double)tp.tv_sec + ((double)(unsigned)tp.tv_usec)*.000001;
167 }
168 if (user || sys)
169 times(&tms1);
170 gettimeofday(&tp, &tzp);
171 time1 = (double)tp.tv_sec + ((double)(unsigned)tp.tv_usec)*.000001;
172 if (user)
173 *user = (float)(tms1.tms_utime/*-tms0.tms_utime*/) / HZ;
174 if (sys)
175 *sys = (float)(tms1.tms_stime/*-tms0.tms_stime*/) / HZ;
176 if (real)
177 *real = time1 - time0;
178 }
179 #endif
180
181 static void
_times(double * user,double * sys,double * real)182 _times(double *user, double *sys, double *real)
183 {
184 #if !ibm6000 && !sun4 && !solaris
185 #if ibmpvs && !paxc
186 static int been_here, svs;
187
188 if (!been_here) {
189 svs = getenv("GENERICI860")? 0 : 1;
190 been_here = 1;
191 }
192
193 if (svs)
194 _times_svs(user, sys, real);
195 else
196 #endif
197 _times_unix(user, sys, real);
198 #else
199 _times_ibmsun4(user, sys, real);
200 #endif
201 }
202
203
204 double
DXGetTime(void)205 DXGetTime(void)
206 {
207 double t;
208 _times(NULL, NULL, &t);
209 return t;
210 }
211
212 void
DXWaitTime(double seconds)213 DXWaitTime(double seconds)
214 {
215 #if defined(intelnt) || defined(WIN32)
216 Sleep(seconds*1000);
217 #else
218 #if ibmpvs || hp700 || aviion
219
220 double old;
221 old = DXGetTime();
222
223 while (DXGetTime() - old < seconds)
224 continue;
225
226 #elif ibm6000 || sun4 || macos || linux || freebsd || cygwin
227
228 usleep((int)(1000000.0 * seconds));
229
230 #elif sgi
231
232 sginap((int)(CLK_TCK * seconds));
233
234 #else
235
236 sleep((int)seconds); /* this will only sleep in whole seconds */
237
238 #endif
239 #endif
240 }
241
242 /*
243 * time marking
244 */
245
246 Error
_dxf_inittiming(void)247 _dxf_inittiming(void)
248 {
249 if (!ti) {
250 ti = (struct ti *) DXAllocateZero(sizeof(struct ti));
251 if (!ti)
252 return ERROR;
253 ti->procs = (struct _proc *)
254 DXAllocateZero(DXProcessors(0) * sizeof(struct _proc));
255 if (!ti->procs) {
256 DXFree((Pointer)ti);
257 return ERROR;
258 }
259 _times(NULL, NULL, NULL);
260 }
261 return OK;
262 }
263
264 static
265 void
mark(char * s,int global)266 mark(char *s, int global)
267 {
268 static int been_here;
269 struct _proc *proc;
270 struct event *event;
271 int id = DXProcessorId();
272
273 if (!been_here) {
274 DXinitdx();
275 been_here = 1;
276 }
277 proc = &ti->procs[id];
278 if (proc->n >= EVENTS)
279 return;
280 event = &proc->events[proc->n++];
281 _times(&event->user, &event->sys, &event->real);
282 event->global = global;
283 strncpy(event->label, s, sizeof(event->label)-1);
284 event->label[sizeof(event->label)-1] = '\0';
285 }
286
287
DXMarkTime(char * s)288 void DXMarkTime (char *s) {if (ti->trace) mark(s, 1);}
DXMarkTimeLocal(char * s)289 void DXMarkTimeLocal (char *s) {if (ti->trace) mark(s, 0);}
DXMarkTimeX(char * s)290 void DXMarkTimeX (char *s) { mark(s, 1);}
DXMarkTimeLocalX(char * s)291 void DXMarkTimeLocalX (char *s) { mark(s, 0);}
292
293
294 void
DXPrintTimes(void)295 DXPrintTimes(void)
296 {
297 int i, id=0;
298 static struct last glob;
299 struct _proc *proc = NULL, *p;
300 struct event *event;
301 struct last *last;
302 DXBeginLongMessage();
303
304 for (;;) {
305
306 /* find latest event not yet printed */
307 event = NULL;
308 for (i=0, p=ti->procs; i<DXProcessors(0); i++, p++) {
309 if (p->printed < p->n) {
310 struct event *e = &p->events[p->printed];
311 if (!event || e->real < event->real)
312 id = i, proc = p, event = e;
313 }
314 }
315 if (!event)
316 break;
317 proc->printed += 1;
318 last = &proc->last;
319
320 if (event->global) {
321 /*
322 * Measure global real time delta from last global event.
323 * Measure user and system delta from last event on
324 * this processor.
325 */
326 DXMessage("--: %16s %10.6f+%10.6f=%10.6f (%6.2fu, %6.2fs)\n",
327 event->label, glob.real,event->real-glob.real, event->real,
328 event->user-last->user, event->sys-last->sys);
329 glob.real = event->real;
330 } else {
331 /*
332 * Measure real local time delta from last event on this processor
333 * or last global event, whichever is more recent. Measure user
334 * and sys time delta from last event on this processor.
335 */
336 double real = last->real>glob.real? last->real : glob.real;
337 DXMessage("%2d: %16s %10.6f+%10.6f=%10.6f (%6.2fu, %6.2fs)\n",
338 id, event->label, real, event->real-real, event->real,
339 event->user-last->user, event->sys-last->sys);
340 }
341 last->user = event->user;
342 last->sys = event->sys;
343 last->real = event->real;
344 }
345
346 DXEndLongMessage();
347
348 /* reset all per-processor information to 0 */
349 for (i=0, p=ti->procs; i < DXProcessors(0); i++, p++)
350 p->n = p->printed = 0;
351 }
352