From 243f5a8f3bb51a219cf44a64bdcd64bd676ffece Mon Sep 17 00:00:00 2001 From: tradke Date: Mon, 20 Dec 2004 16:51:20 +0000 Subject: Andre Werthmann's code to provide a webpage with CCTK timer data. git-svn-id: http://svn.cactuscode.org/arrangements/CactusConnect/HTTPDExtra/trunk@63 61ea717e-8e0c-4c3c-b38e-e9c67f54f1f1 --- src/Startup.c | 4 + src/TimerInfo.c | 741 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/make.code.defn | 2 +- 3 files changed, 746 insertions(+), 1 deletion(-) create mode 100644 src/TimerInfo.c diff --git a/src/Startup.c b/src/Startup.c index 8f5b2e5..3791230 100644 --- a/src/Startup.c +++ b/src/Startup.c @@ -33,6 +33,7 @@ int HTTPUTILS_Startup(void); HTTPUTILS_RegisterPages HTTP_util_RegisterIOPages HTTPDExtra_RegisterProcessorsPages + HTTPDExtra_RegisterTimerInfoPages @returntype int @returndesc @@ -45,6 +46,7 @@ int HTTPUTILS_Startup(void) extern int HTTPUTILS_RegisterPages(void); extern int HTTP_util_RegisterIOPages(void); extern int HTTPDExtra_RegisterProcessorsPages(void); + extern int HTTPDExtra_RegisterTimerInfoPages(void); HTTPDExtra_CollateHostData(); @@ -55,5 +57,7 @@ int HTTPUTILS_Startup(void) HTTPDExtra_RegisterProcessorsPages(); + HTTPDExtra_RegisterTimerInfoPages(); + return 0; } diff --git a/src/TimerInfo.c b/src/TimerInfo.c new file mode 100644 index 0000000..5d3d10c --- /dev/null +++ b/src/TimerInfo.c @@ -0,0 +1,741 @@ + /*@@ + @file TimerInfo.c + @date Wed Dec 16 2004 + @author Andre Werthmann + @desc + Pages about CCTK timers + @enddesc + @version $Header$ + @@*/ + +#include "cctk.h" + +#include +#include + +#include "util_String.h" + +#include "httpextra_HostNames.h" +#include "http_Content.h" + +/* SW Temporary, while testing the SString module*/ +#include "CactusConnect/HTTPD/src/SString.h" +#include "CactusConnect/HTTPD/src/SString_Namespace.h" + +static const char *rcsid = "$Header$"; + +CCTK_FILEVERSION(CactusConnect_HTTPDExtra_TimerInfo_c) + +/******************************************************************** + ********************* Local Data Types *********************** + ********************************************************************/ + +#define DECBUFSIZE 64 +#define NUMTIMERTYPES 19 +/* static field with all know schedule bin names */ +static char* TI_ttypes[NUMTIMERTYPES] = +{ + "CCTK_STARTUP", + "CCTK_WRAGH", + "CCTK_PARAMCHECK", + "CCTK_BASEGRID", + "CCTK_INITIAL", + "CCTK_POSTREGRID", + "CCTK_POSTRESTRICTINITIAL", + "CCTK_POSTINITIAL", + "CCTK_POSTSTEP", + "CCTK_RECOVER_VARIABLES", + "CCTK_POST_RECOVER_VARIABLES", + "CCTK_CPINITIAL", + "CCTK_ANALYSIS", + "CCTK_PRESTEP", + "CCTK_EVOL", + "CCTK_POSTRESTRICT", + "CCTK_CHECKPOINT", + "CCTK_TERMINATE", + "CCTK_SHUTDOWN" +}; +/* actual number of not resolved schedule bin names */ +static int TI_nettypes=0; +/* actual number of allocated entries in the field */ +static int TI_maxnettypes=0; +/* dynamic field that holds the names of not resolved schedule bin names */ +static char** TI_ettypes=NULL; +/* dynamic field that holds the values of clocks for timers for nicer html output later */ +static double** TI_oldtimes=NULL; +static int TI_oldntimers=0; +static int TI_oldnclocks=0; + +/******************************************************************** + ********************* Local Routine Prototypes ********************* + ********************************************************************/ + +static int TimerInfoPage(const cGH *cctkGH, httpRequest *request, void *data); + +/* local list implementation, comments below */ +static void TI_initExtraTimerTypeField(void); +static int TI_isElement(char* selem); +static int TI_insertElement(char* selem); +static void TI_deleteExtraTimerTypeField(void); +static void TI_printExtraTimerTypeField(void); + +/* helper functions, comments below */ +static int TI_isTimerType(const char* tName, char* tType); +static char* TI_thornName(const char* tn); +static char* TI_funcName(const char* tn); +static char* TI_schedName(const char* tn); + +/******************************************************************** + ********************* Other Routine Prototypes ********************* + ********************************************************************/ + +/******************************************************************** + ********************* Local Data ***************************** + ********************************************************************/ + +/******************************************************************** + ********************* External Routines ********************** + ********************************************************************/ + + /*@@ + @routine HTTPDExtra_RegisterTimerInfoPages + @date Thu Dec 09 18:12:43 2004 + @author Andre Werthmann + @desc + Httpd utils registration routine. + @enddesc +@@*/ +int HTTPDExtra_RegisterTimerInfoPages(void) +{ + int i; + int ntimers=0, nclocks=0; + + /* Register the group info page. */ + HTTP_RegisterPage("/TimerInfo", TimerInfoPage, NULL); + + HTTP_ContentLink("/TimerInfo/index.html", "Timer Information", + "CCTK Timer information", + HTTP_QUICKLINK); + + + return 0; +} + +/******************************************************************** + ********************* Local Routines ************************* + ********************************************************************/ + + + +/****************************************************************************** + *************************** Groups Page ************************************** + ******************************************************************************/ + + /*@@ + @routine TimerInfoPage + @date Thu Dec 09 18:12:43 2004 + @author Andre Werthmann + @desc + Displays the cctk timer description page. + @enddesc +@@*/ +static int TimerInfoPage(const cGH *cctkGH, httpRequest *request, void *data) +{ + int retval = 0; + int ntimers = 0, nt = 0; + int nclocks = 0, nc = 0; + int i, j; + char *sdata; + char *sbuff; + String *message = String_New(); + cTimerData *tdata; + + HTTP_SendOKHeader( request ); + + HTTP_SetDoctype( message ); + HTTP_SendString(request, message); + + /* Start the page */ + HTTP_Send(request, "\n\n"); + HTTP_Send(request, "Cactus Simulation CCTK Timer Information\n"); + + HTTP_SetHeadInfo( message); + HTTP_SendString(request, message ); + + HTTP_Send(request, "\n"); + + HTTP_Send(request, "\n\n"); + + /* HTTP_Write out the header part. */ + HTTP_SetContentHeaderString(cctkGH, 0, message, NULL); + retval = HTTP_SendString(request, message); + + HTTP_Send(request, "

CCTK Timer Information

\n"); + + HTTP_Send(request, "
(changed values since last refresh are in bold characters)
\n
"); + + /* init timer data */ + tdata=CCTK_TimerCreateData(); + ntimers = CCTK_NumTimers(); + nclocks = tdata->n_vals; + + /** init the timer clocks buffer + * for every clock and every timer store an old value to + * enhance html output of changed values + * format is: TI_oldtimes[ClockNumber][TimerNumber] + * memory is allocated dynamically if there are new timers and/or clocks + * during computation + */ + if (nclocks != TI_oldnclocks) + { + TI_oldtimes=realloc(TI_oldtimes, nclocks*sizeof(double*)); + for (i=TI_oldnclocks; iTimers which are associated with schedule bins\n"); + + /* set table header */ + SetToCString(message, "
\n\n"); + + /* timer type - table header */ + ConcatCString(message, ""); + + /* thorn name - table header */ + ConcatCString(message, ""); + + /* description name - table header */ + ConcatCString(message, ""); + + /* clock names - table header */ + CCTK_TimerI(0, tdata); + for (i=0; i"); + ConcatCString(message, tdata->vals[i].heading); + ConcatCString(message, " ("); + ConcatCString(message, tdata->vals[i].units); + ConcatCString(message, ")"); + } + ConcatCString(message, ""); + HTTP_SendString(request, message); + + /* parse schedule bins */ + for (i=0; i\n"); + + /* timer type, first column */ + ConcatCString(message, "\n"); + + /* thorn name, second column */ + ConcatCString(message, "\n"); + + /* description */ + ConcatCString(message, "\n"); + + /* timer clocks, fourth... (fourth+number clocks) column */ + for (nc=0; ncvals[nc].heading); + ConcatCString(message, "\">"); + switch (tdata->vals[nc].type) + { + case val_int: + ConcatDecimal(message, tdata->vals[nc].val.i); + break; + case val_long: + ConcatDecimal(message, tdata->vals[nc].val.l); + break; + case val_double: + /* printf("res(%s): %f\n", CCTK_TimerName(nt), tdata->vals[nc].resolution); */ + /* ConcatDouble doesn't work correctly, cuts 0.0002 to 0.2 */ + /* ConcatDouble(message, tdata->vals[nc].val.d); */ + sdata = (char*) malloc(DECBUFSIZE); + snprintf(sdata, DECBUFSIZE, "%f", tdata->vals[nc].val.d); + + /** if the new value is different from the old one + * (changed) print it in bold characters + */ + if ( TI_oldtimes[nc][nt] != tdata->vals[nc].val.d ) + { + ConcatCString(message, ""); + ConcatCString(message, sdata); + ConcatCString(message, ""); + } + else + { + ConcatCString(message, sdata); + } + free(sdata); + /* old value = new value */ + TI_oldtimes[nc][nt]=tdata->vals[nc].val.d; + break; + default: + ConcatCString(message, "unknown value type"); + break; + } + ConcatCString(message, "\n"); + } + /* end table row */ + ConcatCString(message, "\n"); + HTTP_SendString(request, message); + } + } + } + retval = HTTP_Send(request, "
Schedule BinThorn NameDescription
\n"); + sbuff=TI_schedName(TI_ttypes[i]); + ConcatCString(message, sbuff); + free(sbuff); + ConcatCString(message, ""); + sbuff=TI_thornName(CCTK_TimerName(nt)); + ConcatCString(message, sbuff); + free(sbuff); + ConcatCString(message, ""); + sbuff=TI_funcName(CCTK_TimerName(nt)); + ConcatCString(message, sbuff); + free(sbuff); + ConcatCString(message, "
\n
\n
\n"); + + HTTP_Send(request, "

Timers which are associated with schedule groups

\n"); + + /* init the (char*) timer list of schedule bins which couldn't be associated */ + TI_initExtraTimerTypeField(); + + /* start of second table */ + /* set table header */ + SetToCString(message, "
\n\n"); + + /* timer type - table header */ + ConcatCString(message, ""); + + /* thorn name - table header */ + ConcatCString(message, ""); + + /* description name - table header */ + ConcatCString(message, ""); + + /* clock names - table header */ + CCTK_TimerI(0, tdata); + for (i=0; i"); + ConcatCString(message, tdata->vals[i].heading); + ConcatCString(message, " ("); + ConcatCString(message, tdata->vals[i].units); + ConcatCString(message, ")"); + } + ConcatCString(message, ""); + HTTP_SendString(request, message); + + /* second table content */ + for (i=0; i\n"); + + /* timer type, first column */ + ConcatCString(message, "\n"); + + /* thorn name, second column */ + ConcatCString(message, "\n"); + + /* description */ + ConcatCString(message, "\n"); + + /* timer clocks, fourth... (fourth+number clocks) column */ + for (nc=0; ncvals[nc].heading); + ConcatCString(message, "\">"); + + switch (tdata->vals[nc].type) + { + case val_int: + ConcatDecimal(message, tdata->vals[nc].val.i); + break; + case val_long: + ConcatDecimal(message, tdata->vals[nc].val.l); + break; + case val_double: + /* ConcatDouble doesn't work correctly, cuts 0.0002 to 0.2 */ + /* ConcatDouble(message, tdata->vals[nc].val.d); */ + + sdata = (char*) malloc(DECBUFSIZE); + snprintf(sdata, DECBUFSIZE, "%f", tdata->vals[nc].val.d); + + /** if the new value is different from the old one + * (changed) print it in bold characters + */ + if ( TI_oldtimes[nc][nt] != tdata->vals[nc].val.d ) + { + ConcatCString(message, ""); + ConcatCString(message, sdata); + ConcatCString(message, ""); + } + else + { + ConcatCString(message, sdata); + } + free(sdata); + /* old value = new value */ + TI_oldtimes[nc][nt]=tdata->vals[nc].val.d; + + break; + default: + ConcatCString(message, "unknown value type"); + break; + } + ConcatCString(message, "\n"); + } + /* end table row */ + ConcatCString(message, "\n"); + HTTP_SendString(request, message); + } + } + } + + HTTP_Send(request, "
Schedule GroupThorn NameDescription
\n"); + sbuff=TI_schedName(TI_ettypes[i]); + ConcatCString(message, sbuff); + free(sbuff); + ConcatCString(message, ""); + sbuff=TI_thornName(CCTK_TimerName(nt)); + ConcatCString(message, sbuff); + free(sbuff); + ConcatCString(message, ""); + sbuff=TI_funcName(CCTK_TimerName(nt)); + ConcatCString(message, sbuff); + free(sbuff); + ConcatCString(message, "
\n
\n"); + + /* free the allocated memory for the extra timer names - list */ + TI_deleteExtraTimerTypeField(); + + /* free timer structure memory */ + CCTK_TimerDestroyData(tdata); + + HTTP_SetContentFooterString(cctkGH, 0, message); + retval = HTTP_SendString(request, message); + + String_Delete( message ); + + return retval; +} + + +/* local list implementation - helper functions */ + +/** init the local extra timer list, has to be called first + * creates a list of all available extra timer types + */ +/*@@ + @routine TI_initExtraTimerTypeField + @date Thu Dec 09 18:12:43 2004 + @author Andre Werthmann + @desc + creates a list of all available extra timer types + @enddesc + @calls + TI_isElement, TI_insertElement + @calledby + TimerInfoPage +@@*/ +static void TI_initExtraTimerTypeField(void) +{ + int i; + int nt=CCTK_NumTimers(); + char* temp; + int diff = strlen("in "); + + TI_nettypes=0; + + for (i=0; i=2) + { + if (TI_insertElement(temp+diff)) + { + /* should never happen, only if system is out of memory... */ + CCTK_WARN (0, "out of memory !"); + } + } + } + } + } + } +} + +/* checks if a element is member of the list */ +/*@@ + @routine TI_isElement + @date Thu Dec 09 18:12:43 2004 + @author Andre Werthmann + @desc + checks if a element is member of the list + @enddesc + @calledby + TI_initExtraTimerTypeField + @@*/ +static int TI_isElement(char* selem) +{ + int i; + + for (i=0; i= TI_maxnettypes ) + { + TI_ettypes=realloc(TI_ettypes, (TI_maxnettypes+30)*sizeof(char*)); + TI_maxnettypes+=30; + } + /* out of memory ? */ + if (TI_ettypes==NULL) return 1; + + TI_ettypes[TI_nettypes]=(char*) strdup(selem); + TI_nettypes++; + return 0; +} + +/* tests whether a timer is the timer type */ +/*@@ + @routine TI_isTimerType + @date Thu Dec 09 18:12:43 2004 + @author Andre Werthmann + @desc + tests whether a timer is the timer type + @enddesc + @calledby + TimerInfoPage +@@*/ +static int TI_isTimerType(const char* tName, char* tType) +{ + char* temp=strstr(tName, tType); + if (temp) + { + return 1; + } + else + { + return 0; + } +} + +/* deletes all temporary allocated memory */ +/*@@ + @routine TI_deleteExtraTimerTypeField + @date Thu Dec 09 18:12:43 2004 + @author Andre Werthmann + @desc + deletes all temporary allocated memory + @enddesc + @calledby + TimerInfoPage +@@*/ +static void TI_deleteExtraTimerTypeField(void) +{ + int i; + + for (i=0; i