/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ #include #include #include #include #include #if DXD_HAS_UNIX_SYS_INCLUDES #include #include #include #else #include #endif #ifndef HZ #define HZ 60 #endif #define EVENTS 2000 static struct ti { int trace; /* whether to trace times or not */ struct _proc { struct event { /* per event info: */ double user, sys, real; /* time of this event */ char label[16]; /* this event's label */ int id; /* processor on which it ran */ int global; /* whether it is global or local */ } events[EVENTS]; /* one per event */ int n; /* number of events this processor */ int printed; /* count for printing */ struct last { /* last printed event time */ double user, sys, real; /* user, system, real times */ } last; /* per processor */ } *procs; /* one per processor */ } *ti = NULL; /* ptr to struct in global memory */ void DXTraceTime(int t) { static int been_here; if (!been_here) { DXinitdx(); been_here = 1; } if (ti) ti->trace = t; } /* * Internal routine: get a time split, measured in * seconds since the first time split */ #if ibmpvs && !paxc static void _times_svs(double *user, double *sys, double *real) { static struct tms tms0; struct tms tms1; static double time0; double time1; extern double double_time(); static int fast; if (!time0) { times(&tms0); time0 = double_time(); fast = getenv("SLOW")? 0 : 1; } if (!fast && (user || sys)) times(&tms1); time1 = double_time(); if (user) *user = fast? 0 : (float)(tms1.tms_utime-tms0.tms_utime) / HZ; if (sys) *sys = fast? 0 : (float)(tms1.tms_stime-tms0.tms_stime) / HZ; if (real) *real = time1-time0; } #endif #if defined(os2) || defined(DXD_WIN) static void _times_unix(double *user, double *sys, double *real) { static clock_t time0 = 0; static time_t rtime0 = 0; clock_t time1; time_t rtime1; if (!time0) { time0 = clock(); rtime0 = time(0); } time1 = clock(); rtime1 = time(0); if (user) *user = (float)(time1) / CLOCKS_PER_SEC; if (sys) *sys = (float)(time1) / CLOCKS_PER_SEC; if (real) *real = (float)(rtime1-rtime0); } #else static void _times_unix(double *user, double *sys, double *real) { static struct tms tms0; struct tms tms1; static int time0; int time1; if (!time0) time0 = times(&tms0); time1 = times(&tms1); if (user) *user = (float)(tms1.tms_utime/*-tms0.tms_utime*/) / HZ; if (sys) *sys = (float)(tms1.tms_stime/*-tms0.tms_stime*/) / HZ; if (real) *real = (float)(time1-time0) / HZ; } #endif #if ibm6000 || sun4 || solaris static void _times_ibmsun4(double *user, double *sys, double *real) { static struct tms tms0; struct tms tms1; struct timeval tp; struct timezone tzp; static double time0; double time1; if (!time0) { times(&tms0); gettimeofday(&tp, &tzp); time0 = (double)tp.tv_sec + ((double)(unsigned)tp.tv_usec)*.000001; } if (user || sys) times(&tms1); gettimeofday(&tp, &tzp); time1 = (double)tp.tv_sec + ((double)(unsigned)tp.tv_usec)*.000001; if (user) *user = (float)(tms1.tms_utime/*-tms0.tms_utime*/) / HZ; if (sys) *sys = (float)(tms1.tms_stime/*-tms0.tms_stime*/) / HZ; if (real) *real = time1 - time0; } #endif static void _times(double *user, double *sys, double *real) { #if !ibm6000 && !sun4 && !solaris #if ibmpvs && !paxc static int been_here, svs; if (!been_here) { svs = getenv("GENERICI860")? 0 : 1; been_here = 1; } if (svs) _times_svs(user, sys, real); else #endif _times_unix(user, sys, real); #else _times_ibmsun4(user, sys, real); #endif } double DXGetTime(void) { double t; _times(NULL, NULL, &t); return t; } void DXWaitTime(double seconds) { #ifdef DXD_WIN Sleep(seconds*1000); #else #if ibmpvs || hp700 || aviion double old; old = DXGetTime(); while (DXGetTime() - old < seconds) continue; #elif ibm6000 || sun4 usleep((int)(1000000.0 * seconds)); #elif sgi sginap((int)(CLK_TCK * seconds)); #else sleep((int)seconds); /* this will only sleep in whole seconds */ #endif #endif } /* * time marking */ Error _dxf_inittiming() { if (!ti) { ti = (struct ti *) DXAllocateZero(sizeof(struct ti)); if (!ti) return ERROR; ti->procs = (struct _proc *) DXAllocateZero(DXProcessors(0) * sizeof(struct _proc)); if (!ti->procs) { DXFree((Pointer)ti); return ERROR; } _times(NULL, NULL, NULL); } return OK; } static void mark(char *s, int global) { static int been_here; struct _proc *proc; struct event *event; int id = DXProcessorId(); if (!been_here) { DXinitdx(); been_here = 1; } proc = &ti->procs[id]; if (proc->n >= EVENTS) return; event = &proc->events[proc->n++]; _times(&event->user, &event->sys, &event->real); event->global = global; strncpy(event->label, s, sizeof(event->label)-1); event->label[sizeof(event->label)-1] = '\0'; } void DXMarkTime (char *s) {if (ti->trace) mark(s, 1);} void DXMarkTimeLocal (char *s) {if (ti->trace) mark(s, 0);} void DXMarkTimeX (char *s) { mark(s, 1);} void DXMarkTimeLocalX (char *s) { mark(s, 0);} void DXPrintTimes(void) { int i, id; static struct last glob; struct _proc *proc, *p; struct event *event; struct last *last; DXBeginLongMessage(); for (;;) { /* find latest event not yet printed */ event = NULL; for (i=0, p=ti->procs; iprinted < p->n) { struct event *e = &p->events[p->printed]; if (!event || e->real < event->real) id = i, proc = p, event = e; } } if (!event) break; proc->printed += 1; last = &proc->last; if (event->global) { /* * Measure global real time delta from last global event. * Measure user and system delta from last event on * this processor. */ DXMessage("--: %16s %10.6f+%10.6f=%10.6f (%6.2fu, %6.2fs)\n", event->label, glob.real,event->real-glob.real, event->real, event->user-last->user, event->sys-last->sys); glob.real = event->real; } else { /* * Measure real local time delta from last event on this processor * or last global event, whichever is more recent. Measure user * and sys time delta from last event on this processor. */ double real = last->real>glob.real? last->real : glob.real; DXMessage("%2d: %16s %10.6f+%10.6f=%10.6f (%6.2fu, %6.2fs)\n", id, event->label, real, event->real-real, event->real, event->user-last->user, event->sys-last->sys); } last->user = event->user; last->sys = event->sys; last->real = event->real; } DXEndLongMessage(); /* reset all per-processor information to 0 */ memset(ti->procs, 0, sizeof(ti->procs)); }