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>
|
Sat Jul 7 18:58:56 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
||||||
|
|
||||||
* libxslt/templates.c libxslt/transform.c libxslt/transform.h
|
* libxslt/templates.c libxslt/transform.c libxslt/transform.h
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
#undef HAVE_FLOOR
|
#undef HAVE_FLOOR
|
||||||
#undef HAVE_FABS
|
#undef HAVE_FABS
|
||||||
|
|
||||||
|
/* Define if you have the gettimeofday function. */
|
||||||
|
#undef HAVE_GETTIMEOFDAY
|
||||||
|
|
||||||
/* Define if you have the <ansidecl.h> header file. */
|
/* Define if you have the <ansidecl.h> header file. */
|
||||||
#undef HAVE_ANSIDECL_H
|
#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,
|
AC_CHECK_FUNC(fabs, , AC_CHECK_LIB(m, pow,
|
||||||
[M_LIBS="-lm"; AC_DEFINE(HAVE_FABS)]))
|
[M_LIBS="-lm"; AC_DEFINE(HAVE_FABS)]))
|
||||||
|
AC_CHECK_FUNCS(gettimeofday)
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl Perl is just needed for generating some data for XSLtmark
|
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) \
|
#define PUSH_AND_POP(scope, type, name) \
|
||||||
scope int name##Push(xsltTransformContextPtr ctxt, type value) { \
|
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) { \
|
if (ctxt->name##Nr >= ctxt->name##Max) { \
|
||||||
ctxt->name##Max *= 2; \
|
ctxt->name##Max *= 2; \
|
||||||
ctxt->name##Tab = (type *) xmlRealloc(ctxt->name##Tab, \
|
ctxt->name##Tab = (type *) xmlRealloc(ctxt->name##Tab, \
|
||||||
@@ -94,7 +104,7 @@ scope type name##Pop(xsltTransformContextPtr ctxt) { \
|
|||||||
if (ctxt->name##Nr > 0) \
|
if (ctxt->name##Nr > 0) \
|
||||||
ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \
|
ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \
|
||||||
else \
|
else \
|
||||||
ctxt->name = NULL; \
|
ctxt->name = (type) 0; \
|
||||||
ret = ctxt->name##Tab[ctxt->name##Nr]; \
|
ret = ctxt->name##Tab[ctxt->name##Nr]; \
|
||||||
ctxt->name##Tab[ctxt->name##Nr] = 0; \
|
ctxt->name##Tab[ctxt->name##Nr] = 0; \
|
||||||
return(ret); \
|
return(ret); \
|
||||||
@@ -105,6 +115,7 @@ scope type name##Pop(xsltTransformContextPtr ctxt) { \
|
|||||||
*/
|
*/
|
||||||
PUSH_AND_POP(static, xsltTemplatePtr, templ)
|
PUSH_AND_POP(static, xsltTemplatePtr, templ)
|
||||||
PUSH_AND_POP(static, xsltStackElemPtr, vars)
|
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->varsMax = 5;
|
||||||
cur->vars = NULL;
|
cur->vars = NULL;
|
||||||
cur->varsBase = 0;
|
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;
|
cur->style = style;
|
||||||
xmlXPathInit();
|
xmlXPathInit();
|
||||||
@@ -968,6 +986,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|||||||
xmlNodePtr oldInst = NULL;
|
xmlNodePtr oldInst = NULL;
|
||||||
xmlAttrPtr attrs;
|
xmlAttrPtr attrs;
|
||||||
int oldBase;
|
int oldBase;
|
||||||
|
long start = 0;
|
||||||
|
|
||||||
if ((ctxt == NULL) || (list == NULL))
|
if ((ctxt == NULL) || (list == NULL))
|
||||||
return;
|
return;
|
||||||
@@ -983,7 +1002,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* stack and saves
|
* stack saves, beware ordering of operations counts
|
||||||
*/
|
*/
|
||||||
oldInsert = insert = ctxt->insert;
|
oldInsert = insert = ctxt->insert;
|
||||||
oldInst = ctxt->inst;
|
oldInst = ctxt->inst;
|
||||||
@@ -995,6 +1014,8 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|||||||
ctxt->node = node;
|
ctxt->node = node;
|
||||||
if (ctxt->profile) {
|
if (ctxt->profile) {
|
||||||
templ->nbCalls++;
|
templ->nbCalls++;
|
||||||
|
start = xsltTimestamp();
|
||||||
|
profPush(ctxt, 0);
|
||||||
}
|
}
|
||||||
templPush(ctxt, templ);
|
templPush(ctxt, templ);
|
||||||
#ifdef WITH_XSLT_DEBUG_PROCESS
|
#ifdef WITH_XSLT_DEBUG_PROCESS
|
||||||
@@ -1019,30 +1040,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|||||||
xsltGenericDebug(xsltGenericDebugContext,
|
xsltGenericDebug(xsltGenericDebugContext,
|
||||||
"xsltApplyOneTemplate: insert == NULL !\n");
|
"xsltApplyOneTemplate: insert == NULL !\n");
|
||||||
#endif
|
#endif
|
||||||
ctxt->node = oldCurrent;
|
goto error;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_XSLT_ELEM(cur)) {
|
if (IS_XSLT_ELEM(cur)) {
|
||||||
@@ -1202,6 +1200,7 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|||||||
}
|
}
|
||||||
} while (cur != NULL);
|
} while (cur != NULL);
|
||||||
}
|
}
|
||||||
|
error:
|
||||||
ctxt->node = oldCurrent;
|
ctxt->node = oldCurrent;
|
||||||
ctxt->inst = oldInst;
|
ctxt->inst = oldInst;
|
||||||
ctxt->insert = oldInsert;
|
ctxt->insert = oldInsert;
|
||||||
@@ -1224,6 +1223,18 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|||||||
if (templ != NULL) {
|
if (templ != NULL) {
|
||||||
ctxt->varsBase = oldBase;
|
ctxt->varsBase = oldBase;
|
||||||
templPop(ctxt);
|
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 */
|
const char * outputFile; /* the output URI if known */
|
||||||
|
|
||||||
int profile; /* is this run profiled */
|
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
|
#ifdef LIBXML_XINCLUDE_ENABLED
|
||||||
printf(" --xinclude : do XInclude processing on document intput\n");
|
printf(" --xinclude : do XInclude processing on document intput\n");
|
||||||
#endif
|
#endif
|
||||||
printf(" --profile : dump profiling informations \n");
|
printf(" --profile or --norman : dump profiling informations \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -192,6 +192,9 @@ main(int argc, char **argv)
|
|||||||
} else if ((!strcmp(argv[i], "-profile")) ||
|
} else if ((!strcmp(argv[i], "-profile")) ||
|
||||||
(!strcmp(argv[i], "--profile"))) {
|
(!strcmp(argv[i], "--profile"))) {
|
||||||
profile++;
|
profile++;
|
||||||
|
} else if ((!strcmp(argv[i], "-norman")) ||
|
||||||
|
(!strcmp(argv[i], "--norman"))) {
|
||||||
|
profile++;
|
||||||
} else if ((!strcmp(argv[i], "-warnnet")) ||
|
} else if ((!strcmp(argv[i], "-warnnet")) ||
|
||||||
(!strcmp(argv[i], "--warnnet"))) {
|
(!strcmp(argv[i], "--warnnet"))) {
|
||||||
xmlSetExternalEntityLoader(xsltNoNetExternalEntityLoader);
|
xmlSetExternalEntityLoader(xsltNoNetExternalEntityLoader);
|
||||||
|
|||||||
@@ -12,6 +12,15 @@
|
|||||||
#include "libxslt.h"
|
#include "libxslt.h"
|
||||||
|
|
||||||
#include <stdio.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 <stdarg.h>
|
||||||
|
|
||||||
#include <libxml/xmlmemory.h>
|
#include <libxml/xmlmemory.h>
|
||||||
@@ -24,6 +33,16 @@
|
|||||||
#include "xsltInternals.h"
|
#include "xsltInternals.h"
|
||||||
#include "imports.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 *
|
* 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
|
#define MAX_TEMPLATES 10000
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -959,6 +1031,7 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {
|
|||||||
int nb, i,j;
|
int nb, i,j;
|
||||||
int max;
|
int max;
|
||||||
int total;
|
int total;
|
||||||
|
long totalt;
|
||||||
xsltTemplatePtr *templates;
|
xsltTemplatePtr *templates;
|
||||||
xsltStylesheetPtr style;
|
xsltStylesheetPtr style;
|
||||||
xsltTemplatePtr template;
|
xsltTemplatePtr template;
|
||||||
@@ -981,6 +1054,7 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {
|
|||||||
if (nb >= max)
|
if (nb >= max)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (template->nbCalls > 0)
|
||||||
templates[nb++] = template;
|
templates[nb++] = template;
|
||||||
template = template->next;
|
template = template->next;
|
||||||
}
|
}
|
||||||
@@ -990,7 +1064,9 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {
|
|||||||
|
|
||||||
for (i = 0;i < nb -1;i++) {
|
for (i = 0;i < nb -1;i++) {
|
||||||
for (j = i + 1; j < nb; j++) {
|
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];
|
template = templates[j];
|
||||||
templates[j] = templates[i];
|
templates[j] = templates[i];
|
||||||
templates[i] = template;
|
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");
|
"number", "match", "name", "mode");
|
||||||
total = 0;
|
total = 0;
|
||||||
|
totalt = 0;
|
||||||
for (i = 0;i < nb;i++) {
|
for (i = 0;i < nb;i++) {
|
||||||
fprintf(output, "%5d ", i);
|
fprintf(output, "%5d ", i);
|
||||||
if (templates[i]->match != NULL) {
|
if (templates[i]->match != NULL) {
|
||||||
@@ -1027,10 +1104,12 @@ xsltSaveProfiling(xsltTransformContextPtr ctxt, FILE *output) {
|
|||||||
} else {
|
} else {
|
||||||
fprintf(output, "%10s", "");
|
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;
|
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);
|
xmlFree(templates);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,8 @@ int xsltSaveResultToFd (int fd,
|
|||||||
void xsltSaveProfiling (xsltTransformContextPtr ctxt,
|
void xsltSaveProfiling (xsltTransformContextPtr ctxt,
|
||||||
FILE *output);
|
FILE *output);
|
||||||
|
|
||||||
|
long xsltTimestamp (void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user