/* File: chrono.c * Author: Jean Thierry-Mieg (mieg@mrc-lmb.cam.ac.uk) * Copyright (C) J Thierry-Mieg and R Durbin, 1992 * ------------------------------------------------------------------- * Acedb is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt * ------------------------------------------------------------------- * This file is part of the ACEDB genome database package, written by * Richard Durbin (MRC LMB, UK) rd@mrc-lmb.cam.ac.uk, and * Jean Thierry-Mieg (CRBM du CNRS, France) mieg@kaa.cnrs-mop.fr * * Description: General Timing statistics * This package is self contained since any function * called from here cannot be timed. * If you compile without flag CHRONO all calls to the * chrono package just disappear out of the code. * See chrono.h for how this works. * The basis of this code is the UNIX getrusage() routine, * this is _not_ a POSIX call and may not be available on * all platforms. * * * 3 routines are public : * * chrono, chronoReturn and chronoShow * * * * chrono("procedure") switches the timing to "procedure" * * chronoReturn ends it. * * chrono.h defines chrono = chronoSwitch or void * * and chronoReturn = chronoDoReturn or void * * If you compile without flag CHRONO all calls to the * * chrono package just disappear out of the code. * * Exported functions: see chrono.h * HISTORY: * Last edited: May 4 15:35 1999 (edgrif) * * Oct 13 14:37 1998 (edgrif): Removed ACEDB defines, replaced with * function calls. * * Nov 27 12:36 1995 (mieg) * Created: Mon Jun 15 14:42:32 1990 (mieg) *------------------------------------------------------------------- */ /* $Id: chrono.c,v 1.8 1999/09/01 10:36:02 fw Exp $ */ #include "regular.h" /* Specify platforms to run chrono on... */ /* Basically, you can't run this on much, I assume this is because it uses getrusage() to get the timings and this is not a POSIX call. */ #if !(defined(SOLARIS) || defined(MACINTOSH) || defined(IBM) || defined(WIN32) || defined(HP)) #define CHRONO #endif /* If we are on the correct platform then define the chrono stuff. */ /* */ #ifdef CHRONO #include #include #include #include /* subroutines to return info about system and real time */ #define MAXPROC 300 #define HALFMAXCHRONOSTACK 6 #define MAXCHRONOSTACK 2*HALFMAXCHRONOSTACK typedef struct rusage *Timer_ ; static struct rusage previous[1], current[1] ; static char *prok[MAXPROC]; /* proc cannot be redeclared on IBM */ static double tSys[MAXPROC], tUser[MAXPROC] ; static int chMax = 0, call[MAXPROC]; static int chronoIsRunning = FALSE ; static void chronoResume(void) ; static void chronoStart(void), chronoStop(void); void chronoShow(void) ; static MENUOPT chronoMenu[]={ {graphDestroy,"Quit"}, {help,"Help"}, {graphPrint,"Print"}, {chronoStart,"Start"}, {chronoStop,"Stop"}, {chronoResume,"Resume"}, {chronoShow,"Show"}, {0,0} }; static int last = 0 ; static Stack chronoStack = 0 ; /**********************************************/ /* This is not portable at all, we should be using clock ticks to do this, */ /* see a Unix manual.... */ static double MICRO = .000001 ; static double convert (struct timeval *tval) /* conversion to seconds */ { return (double) (tval->tv_sec + MICRO*tval->tv_usec) ; } /******************************************/ static void chronoGo(int i) { getrusage (RUSAGE_SELF,current) ; tSys[i] += convert (¤t->ru_stime) - convert (&previous->ru_stime) ; tUser[i] += convert (¤t->ru_utime) - convert (&previous->ru_utime) ; call[0] ++ ; *previous = *current ; } /******************************************/ static void chronoStart(void) { register int i = MAXPROC; chMax = 1; while (i--) { prok[i] = NULL; call[i] = 0; tSys[i] = tUser[i] = (double) 0; } prok[0] = "Chrono" ; getrusage (RUSAGE_SELF,previous) ; chronoStack = stackReCreate(chronoStack, 64) ; chronoIsRunning = TRUE ; last = 0 ; } /******************************************/ static void chronoStop(void) { chronoIsRunning = FALSE ; last = 0 ; stackClear(chronoStack) ; } /******************************************/ static void chronoResume(void) { chronoIsRunning = TRUE ; last = 0 ; stackClear(chronoStack) ; } /******************************************/ static int alphabetic(void *a,void *b) { return strcmp(prok[*(int*)a], prok[*(int*)b] ) ; } /******************************************/ static Graph chronoGraph = 0; static Array line = 0 ; static void localDestroy(void) { chronoStop() ; chronoGraph = 0 ; arrayDestroy(line); line = 0 ; stackDestroy(chronoStack) ; } /******************************************/ /*********** Pubic Routines ***************/ /******************************************/ /* aliased to chrono in chrono.h */ void chronoSwitch(char *cp) { int i = chMax; if (!chronoIsRunning) return ; while(--i) if (prok[i] == cp) break; if (!i) prok[i = chMax++] = cp; if (chMax >= MAXPROC ) messcrash("overflow in chrono(), increase MAXPROC"); chronoGo(last) ; push(chronoStack, last, int) ; call[i] ++; last = i ; } /*****************************************/ /* aliased to chronoReturn in chrono.h */ void chronoDoReturn(void) { if (!chronoIsRunning) return ; chronoGo(last) ; last = pop(chronoStack, int) ; } /******************************************/ void chronoShow(void) { int i, j, ll = 4 ; double tSysTotal = 0, tUserTotal = 0; if (!line) line = arrayCreate(chMax,int); else arrayMax(line) = 0 ; if(! graphActivate(chronoGraph)) { /* ACEDB-GRAPH INTERFACE: If an acedb display function is registered, */ /* call it, otherwise do our own. The default is as it was in the routine */ /* in graphxt.c */ if (getGraphAcedbDisplayCreate() != NULL && (chronoGraph = (getGraphAcedbDisplayCreate())(getGraphAcedbChronoName()) )) { if (!graphHelp(0)) graphHelp ("Chronometer") ; /* default help unless otherwise * specified in displays.wrm */ } else chronoGraph = graphCreate (TEXT_SCROLL, "", 0.2, 0.1, 0.5, 0.7) ; graphRegister(DESTROY, localDestroy) ; } else graphPop() ; graphClear(); graphTextFormat(FIXED_WIDTH) ; graphColor (BLACK) ; if(!chMax) graphText("Start the chronometer from the pull down menu of this window",4,4) ; else { for (i=0; i", 5, ll) ; graphText(prok[i], 8, ll); graphText(messprintf("%6d",call[i]),22,ll) ; graphText (messprintf("%8.2f %5d",tSys[i], (int)(100 * tSys[i]/(.001+tSysTotal))),30,ll) ; graphText(messprintf("%8.2f %5d ", tUser[i],(int)( 100 * tUser[i]/(.001+tUserTotal))), 46, ll); } } graphLine (29,5,29,ll) ; graphLine (47,5,47,ll) ; graphButtons(chronoMenu, 2, 2, 60) ; graphTextBounds (100,ll + 3) ; graphRedraw() ; graphMenu (chronoMenu); } /*****************************************/ #else /* CHRONO needed if chrono poses a problem on some machines */ void chronoShow(void) { messout("To gain access to the Chronometer,\n recompile with the option -DCHRONO"); } void chronoDoReturn(void) {return ;} void chronoSwitch (char *text) {return ;} #endif /* CHRONO - Macintosh requires in a C comment */ /*****************************************/ /*****************************************/