1
0
mirror of https://gitlab.gnome.org/GNOME/libxslt synced 2025-11-06 23:49:25 +03:00

added gettimeofday() check profiling works option --profile (or --norman

* config.h.in configure.in: added gettimeofday() check
* libxslt/transform.c libxslt/xsltInternals.h libxslt/xsltutils.[ch]:
  profiling works option --profile (or --norman ;)
Daniel
This commit is contained in:
Daniel Veillard
2001-07-07 21:24:06 +00:00
parent 6744bd096b
commit a48ce8ba9d
8 changed files with 142 additions and 33 deletions

View File

@@ -1,3 +1,9 @@
Sat Jul 7 23:19:09 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* config.h.in configure.in: added gettimeofday() check
* libxslt/transform.c libxslt/xsltInternals.h libxslt/xsltutils.[ch]:
profiling works option --profile (or --norman ;)
Sat Jul 7 18:58:56 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* libxslt/templates.c libxslt/transform.c libxslt/transform.h

View File

@@ -12,6 +12,9 @@
#undef HAVE_FLOOR
#undef HAVE_FABS
/* Define if you have the gettimeofday function. */
#undef HAVE_GETTIMEOFDAY
/* Define if you have the <ansidecl.h> header file. */
#undef HAVE_ANSIDECL_H

View File

@@ -52,6 +52,7 @@ AC_CHECK_FUNC(floor, , AC_CHECK_LIB(m, pow,
AC_CHECK_FUNC(fabs, , AC_CHECK_LIB(m, pow,
[M_LIBS="-lm"; AC_DEFINE(HAVE_FABS)]))
AC_CHECK_FUNCS(gettimeofday)
dnl
dnl Perl is just needed for generating some data for XSLtmark

View File

@@ -73,6 +73,16 @@ int xsltMaxDepth = 500;
#define PUSH_AND_POP(scope, type, name) \
scope int name##Push(xsltTransformContextPtr ctxt, type value) { \
if (ctxt->name##Max == 0) { \
ctxt->name##Max = 4; \
ctxt->name##Tab = (type *) xmlMalloc(ctxt->name##Max * \
sizeof(ctxt->name##Tab[0])); \
if (ctxt->name##Tab == NULL) { \
xmlGenericError(xmlGenericErrorContext, \
"malloc failed !\n"); \
return(0); \
} \
} \
if (ctxt->name##Nr >= ctxt->name##Max) { \
ctxt->name##Max *= 2; \
ctxt->name##Tab = (type *) xmlRealloc(ctxt->name##Tab, \
@@ -94,7 +104,7 @@ scope type name##Pop(xsltTransformContextPtr ctxt) { \
if (ctxt->name##Nr > 0) \
ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \
else \
ctxt->name = NULL; \
ctxt->name = (type) 0; \
ret = ctxt->name##Tab[ctxt->name##Nr]; \
ctxt->name##Tab[ctxt->name##Nr] = 0; \
return(ret); \
@@ -105,6 +115,7 @@ scope type name##Pop(xsltTransformContextPtr ctxt) { \
*/
PUSH_AND_POP(static, xsltTemplatePtr, templ)
PUSH_AND_POP(static, xsltStackElemPtr, vars)
PUSH_AND_POP(static, long, prof)
/************************************************************************
* *
@@ -196,6 +207,13 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) {
cur->varsMax = 5;
cur->vars = NULL;
cur->varsBase = 0;
/*
* the profiling stcka is not initialized by default
*/
cur->profTab = NULL;
cur->profNr = 0;
cur->profMax = 0;
cur->prof = 0;
cur->style = style;
xmlXPathInit();
@@ -968,6 +986,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr oldInst = NULL;
xmlAttrPtr attrs;
int oldBase;
long start = 0;
if ((ctxt == NULL) || (list == NULL))
return;
@@ -983,7 +1002,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
}
/*
* stack and saves
* stack saves, beware ordering of operations counts
*/
oldInsert = insert = ctxt->insert;
oldInst = ctxt->inst;
@@ -995,6 +1014,8 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
ctxt->node = node;
if (ctxt->profile) {
templ->nbCalls++;
start = xsltTimestamp();
profPush(ctxt, 0);
}
templPush(ctxt, templ);
#ifdef WITH_XSLT_DEBUG_PROCESS
@@ -1019,30 +1040,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
xsltGenericDebug(xsltGenericDebugContext,
"xsltApplyOneTemplate: insert == NULL !\n");
#endif
ctxt->node = oldCurrent;
ctxt->inst = oldInst;
ctxt->insert = oldInsert;
if (params == NULL)
xsltFreeStackElemList(varsPop(ctxt));
else {
xsltStackElemPtr p, tmp = varsPop(ctxt);
if (tmp != params) {
p = tmp;
while ((p != NULL) && (p->next != params))
p = p->next;
if (p == NULL) {
xsltFreeStackElemList(tmp);
} else {
p->next = NULL;
xsltFreeStackElemList(tmp);
}
}
}
if (templ != NULL) {
ctxt->varsBase = oldBase;
templPop(ctxt);
}
return;
goto error;
}
if (IS_XSLT_ELEM(cur)) {
@@ -1202,6 +1200,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
}
} while (cur != NULL);
}
error:
ctxt->node = oldCurrent;
ctxt->inst = oldInst;
ctxt->insert = oldInsert;
@@ -1224,6 +1223,18 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
if (templ != NULL) {
ctxt->varsBase = oldBase;
templPop(ctxt);
if (ctxt->profile) {
long spent, child, total, end;
end = xsltTimestamp();
child = profPop(ctxt);
total = end - start;
spent = total - child;
templ->time += spent;
if (ctxt->profNr > 0)
ctxt->profTab[ctxt->profNr - 1] += total;
}
}
}

View File

@@ -385,6 +385,10 @@ struct _xsltTransformContext {
const char * outputFile; /* the output URI if known */
int profile; /* is this run profiled */
long prof; /* the current profiled value */
int profNr; /* Nb of templates in the stack */
int profMax; /* Size of the templtaes stack */
long *profTab; /* the profile template stack */
};
/**

View File

@@ -114,7 +114,7 @@ static void usage(const char *name) {
#ifdef LIBXML_XINCLUDE_ENABLED
printf(" --xinclude : do XInclude processing on document intput\n");
#endif
printf(" --profile : dump profiling informations \n");
printf(" --profile or --norman : dump profiling informations \n");
}
int
@@ -192,6 +192,9 @@ main(int argc, char **argv)
} else if ((!strcmp(argv[i], "-profile")) ||
(!strcmp(argv[i], "--profile"))) {
profile++;
} else if ((!strcmp(argv[i], "-norman")) ||
(!strcmp(argv[i], "--norman"))) {
profile++;
} else if ((!strcmp(argv[i], "-warnnet")) ||
(!strcmp(argv[i], "--warnnet"))) {
xmlSetExternalEntityLoader(xsltNoNetExternalEntityLoader);

View File

@@ -12,6 +12,15 @@
#include "libxslt.h"
#include <stdio.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <stdarg.h>
#include <libxml/xmlmemory.h>
@@ -24,6 +33,16 @@
#include "xsltInternals.h"
#include "imports.h"
/* gettimeofday on Windows ??? */
#ifdef WIN32
#ifdef _MSC_VER
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#define gettimeofday(p1,p2)
#define HAVE_GETTIMEOFDAY
#endif /* _MS_VER */
#endif /* WIN32 */
/************************************************************************
* *
* Convenience function *
@@ -941,10 +960,63 @@ xsltSaveResultToFd(int fd, xmlDocPtr result, xsltStylesheetPtr style) {
/************************************************************************
* *
* Generating proviling output *
* Generating profiling informations *
* *
************************************************************************/
/**
* xsltCalibrateTimestamps:
*
* Used for to calibrate the xsltTimestamp() function
* Should work if launched at startup and we don't loose our quantum :-)
*
* Returns the number of milliseconds used by xsltTimestamp()
*/
static long
xsltCalibrateTimestamps(void) {
register int i;
for (i = 0;i < 999;i++)
xsltTimestamp();
return(xsltTimestamp() / 1000);
}
/**
* xsltTimestamp:
*
* Used for gathering profiling data
*
* Returns the number of milliseconds since the beginning of the
* profiling
*/
long
xsltTimestamp(void) {
#ifdef HAVE_GETTIMEOFDAY
static long calibration = -1;
static struct timeval startup;
struct timeval cur;
long msec;
if (calibration == -1) {
gettimeofday(&startup, NULL);
calibration = 0;
calibration = xsltCalibrateTimestamps();
gettimeofday(&startup, NULL);
return(0);
}
gettimeofday(&cur, NULL);
msec = cur.tv_sec - startup.tv_sec;
msec *= 10000;
msec += (cur.tv_usec - startup.tv_usec) / 100;
msec -= calibration;
return((unsigned long) msec);
#else
return(0);
#endif
}
#define MAX_TEMPLATES 10000
/**
@@ -959,6 +1031,7 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {
int nb, i,j;
int max;
int total;
long totalt;
xsltTemplatePtr *templates;
xsltStylesheetPtr style;
xsltTemplatePtr template;
@@ -981,7 +1054,8 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {
if (nb >= max)
break;
templates[nb++] = template;
if (template->nbCalls > 0)
templates[nb++] = template;
template = template->next;
}
@@ -990,7 +1064,9 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {
for (i = 0;i < nb -1;i++) {
for (j = i + 1; j < nb; j++) {
if (templates[i]->nbCalls <= templates[j]->nbCalls) {
if ((templates[i]->time <= templates[j]->time) ||
((templates[i]->time == templates[j]->time) &&
(templates[i]->nbCalls <= templates[j]->nbCalls))) {
template = templates[j];
templates[j] = templates[i];
templates[i] = template;
@@ -998,9 +1074,10 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {
}
}
fprintf(output, "%6s%20s%20s%10s NbCalls\n\n",
fprintf(output, "%6s%20s%20s%10s NbCalls Time 100us\n\n",
"number", "match", "name", "mode");
total = 0;
totalt = 0;
for (i = 0;i < nb;i++) {
fprintf(output, "%5d ", i);
if (templates[i]->match != NULL) {
@@ -1027,10 +1104,12 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {
} else {
fprintf(output, "%10s", "");
}
fprintf(output, " %6d\n", templates[i]->nbCalls);
fprintf(output, " %6d", templates[i]->nbCalls);
fprintf(output, " %6ld\n", templates[i]->time);
total += templates[i]->nbCalls;
totalt += templates[i]->time;
}
fprintf(output, "\n%30s%26s %6d\n", "Total", "", total);
fprintf(output, "\n%30s%26s %6d %6ld\n", "Total", "", total, totalt);
xmlFree(templates);
}

View File

@@ -116,6 +116,8 @@ int xsltSaveResultToFd (int fd,
void xsltSaveProfiling (xsltTransformContextPtr ctxt,
FILE *output);
long xsltTimestamp (void);
#ifdef __cplusplus
}
#endif