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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -116,6 +116,8 @@ int xsltSaveResultToFd (int fd,
|
||||
void xsltSaveProfiling (xsltTransformContextPtr ctxt,
|
||||
FILE *output);
|
||||
|
||||
long xsltTimestamp (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user