From: jbj Date: Mon, 24 Mar 2003 17:25:42 +0000 (+0000) Subject: Add benchmark stopwatch, change precision from milli- to micro-secs. X-Git-Tag: rpm-4.4-release~641 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0b8c3f8319fb610f809f3276ae8001b67b85177d;p=platform%2Fupstream%2Frpm.git Add benchmark stopwatch, change precision from milli- to micro-secs. CVS patchset: 6715 CVS date: 2003/03/24 17:25:42 --- diff --git a/Doxyfile.in b/Doxyfile.in index dffd9e0..9146b35 100644 --- a/Doxyfile.in +++ b/Doxyfile.in @@ -524,6 +524,10 @@ INPUT = \ @top_srcdir@/rpmio/rpmpgp.c \ @top_srcdir@/rpmio/rpmpgp.h \ @top_srcdir@/rpmio/rpmrpc.c \ + @top_srcdir@/rpmio/rpmsq.c \ + @top_srcdir@/rpmio/rpmsq.h \ + @top_srcdir@/rpmio/rpmsw.c \ + @top_srcdir@/rpmio/rpmsw.h \ @top_srcdir@/rpmio/rpmurl.h \ @top_srcdir@/rpmio/strcasecmp.c \ @top_srcdir@/rpmio/stubs.c \ diff --git a/configure.ac b/configure.ac index e41295d..3625759 100644 --- a/configure.ac +++ b/configure.ac @@ -38,7 +38,7 @@ echo " * Here's the rpm-4_1 branch, latest is rpm-4.1.1: * * cvs up -r rpm-4_1 * * * -* Here's the rpm-4_0 branch, latest is rpm-4.0.4: * +* Here's the rpm-4_0 branch, latest is rpm-4.0.5: * * cvs up -r rpm-4_0 * * * **************************************************************************** diff --git a/po/POTFILES.in b/po/POTFILES.in index b555022..4a6abf4 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -73,6 +73,8 @@ rpmio/rpmlog.c rpmio/rpmmalloc.c rpmio/rpmpgp.c rpmio/rpmrpc.c +rpmio/rpmsq.c +rpmio/rpmsw.c rpmio/ugid.c rpmio/url.c tools/rpmcache.c diff --git a/rpmdb/header.c b/rpmdb/header.c index abae5e9..7d33522 100644 --- a/rpmdb/header.c +++ b/rpmdb/header.c @@ -2461,9 +2461,11 @@ static sprintfToken hsaNext(/*@returned@*/ headerSprintfArgs hsa) int_32 type; int_32 count; +/*@-boundswrite@*/ if (!headerNextIterator(hsa->hi, &tagno, &type, NULL, &count)) fmt = NULL; tag->tag = tagno; +/*@=boundswrite@*/ } } @@ -2606,7 +2608,7 @@ bingo: */ static int parseExpression(headerSprintfArgs hsa, sprintfToken token, char * str, /*@out@*/char ** endPtr) - /*@modifies hsa, str, *token, *endPtr @*/ + /*@modifies hsa, str, token, *endPtr @*/ /*@requires maxSet(endPtr) >= 0 @*/; /** @@ -3365,7 +3367,7 @@ static char * singleSprintf(headerSprintfArgs hsa, sprintfToken token, /** * Create an extension cache. - * @param exts + * @param exts headerSprintf extensions * @return new extension cache */ static /*@only@*/ rpmec @@ -3388,7 +3390,7 @@ rpmecNew(const headerSprintfExtension exts) /** * Destroy an extension cache. - * @param extensions + * @param exts headerSprintf extensions * @param ec extension cache * @return NULL always */ diff --git a/rpmio/Makefile.am b/rpmio/Makefile.am index 6cb00ea..2400182 100644 --- a/rpmio/Makefile.am +++ b/rpmio/Makefile.am @@ -17,7 +17,7 @@ pkgincdir = $(pkgincludedir) pkginc_HEADERS = \ argv.h fts.h \ rpmio.h rpmurl.h rpmmacro.h rpmlog.h rpmmessages.h rpmerr.h rpmpgp.h \ - rpmsq.h ugid.h + rpmsq.h rpmsw.h ugid.h noinst_HEADERS = rpmio_internal.h BEECRYPTLOBJS = $(shell cat $(top_builddir)/beecrypt/listobjs) @@ -29,7 +29,7 @@ usrlib_LTLIBRARIES = librpmio.la librpmio_la_SOURCES = \ argv.c digest.c fts.c macro.c \ rpmio.c rpmlog.c rpmmalloc.c \ - rpmpgp.c rpmrpc.c rpmsq.c strcasecmp.c stubs.c url.c ugid.c + rpmpgp.c rpmrpc.c rpmsq.c rpmsw.c strcasecmp.c stubs.c url.c ugid.c librpmio_la_LDFLAGS = -release @VERSION@ $(LDFLAGS) \ $(top_builddir)/file/libfmagic.la \ @WITH_ZLIB_LIB@ \ diff --git a/rpmio/rpmio.c b/rpmio/rpmio.c index 68a591f..684551d 100644 --- a/rpmio/rpmio.c +++ b/rpmio/rpmio.c @@ -354,8 +354,8 @@ static inline /*@null@*/ FD_t XfdNew(const char * msg, fd->ndigests = 0; memset(fd->digests, 0, sizeof(fd->digests)); - (void) gettimeofday(&fd->stats->create, NULL); - fd->stats->begin = fd->stats->create; /* structure assignment */ + (void) rpmswNow(&fd->stats->create); + (void) rpmswNow(&fd->stats->begin); fd->ftpFileDoneNeeded = 0; fd->firstFree = 0; diff --git a/rpmio/rpmio_internal.h b/rpmio/rpmio_internal.h index de2dd21..378e385 100644 --- a/rpmio/rpmio_internal.h +++ b/rpmio/rpmio_internal.h @@ -11,6 +11,7 @@ #include #include +#include /* Drag in the beecrypt includes. */ #include @@ -106,7 +107,7 @@ typedef struct _FDSTACK_s { typedef struct { int count; /*!< Number of operations. */ off_t bytes; /*!< Number of bytes transferred. */ - time_t msecs; /*!< Number of milli-seconds. */ + time_t usecs; /*!< Number of ticks. */ } OPSTAT_t; /** \ingroup rpmio @@ -123,8 +124,8 @@ enum FDSTAT_e { * Cumulative statistics for a descriptor. */ typedef /*@abstract@*/ struct { - struct timeval create; /*!< Structure creation time. */ - struct timeval begin; /*!< Operation start time. */ + struct rpmsw_s create; /*!< Structure creation time. */ + struct rpmsw_s begin; /*!< Operation start time. */ OPSTAT_t ops[4]; /*!< Cumulative statistics. */ } * FDSTAT_t; @@ -371,22 +372,7 @@ void fdPush(FD_t fd, FDIO_t io, void * fp, int fdno) /*@-boundswrite@*/ fd->stats->ops[opx].count++; /*@=boundswrite@*/ - (void) gettimeofday(&fd->stats->begin, NULL); -} - -/** \ingroup rpmio - */ -/*@unused@*/ static inline -time_t tvsub(/*@null@*/ const struct timeval * etv, - /*@null@*/ const struct timeval * btv) - /*@*/ -{ - time_t secs, usecs; - if (etv == NULL || btv == NULL) return 0; - secs = etv->tv_sec - btv->tv_sec; - for (usecs = etv->tv_usec - btv->tv_usec; usecs < 0; usecs += 1000000) - secs++; - return ((secs * 1000) + (usecs/1000)); + (void) rpmswNow(&fd->stats->begin); } /** \ingroup rpmio @@ -395,12 +381,12 @@ time_t tvsub(/*@null@*/ const struct timeval * etv, void fdstat_exit(/*@null@*/ FD_t fd, int opx, ssize_t rc) /*@modifies fd @*/ { - struct timeval end; + struct rpmsw_s end; if (fd == NULL) return; if (rc == -1) fd->syserrno = errno; if (fd->stats == NULL) return; /*@-boundswrite@*/ - (void) gettimeofday(&end, NULL); + (void) rpmswNow(&end); if (rc >= 0) { switch(opx) { case FDSTAT_SEEK: @@ -412,7 +398,7 @@ void fdstat_exit(/*@null@*/ FD_t fd, int opx, ssize_t rc) break; } } - fd->stats->ops[opx].msecs += tvsub(&end, &fd->stats->begin); + fd->stats->ops[opx].usecs += rpmswDiff(&end, &fd->stats->begin); fd->stats->begin = end; /* structure assignment */ /*@=boundswrite@*/ } @@ -425,7 +411,9 @@ void fdstat_print(/*@null@*/ FD_t fd, const char * msg, FILE * fp) /*@globals fileSystem @*/ /*@modifies *fp, fileSystem @*/ { + static int usec_scale = 1000000; int opx; + if (fd == NULL || fd->stats == NULL) return; for (opx = 0; opx < 4; opx++) { OPSTAT_t *ops = &fd->stats->ops[opx]; @@ -433,15 +421,15 @@ void fdstat_print(/*@null@*/ FD_t fd, const char * msg, FILE * fp) switch (opx) { case FDSTAT_READ: if (msg) fprintf(fp, "%s:", msg); - fprintf(fp, "%8d reads, %8ld total bytes in %d.%03d secs\n", + fprintf(fp, "%8d reads, %8ld total bytes in %d.%06d secs\n", ops->count, (long)ops->bytes, - (int)(ops->msecs/1000), (int)(ops->msecs%1000)); + (int)(ops->usecs/usec_scale), (int)(ops->usecs%usec_scale)); /*@switchbreak@*/ break; case FDSTAT_WRITE: if (msg) fprintf(fp, "%s:", msg); - fprintf(fp, "%8d writes, %8ld total bytes in %d.%03d secs\n", + fprintf(fp, "%8d writes, %8ld total bytes in %d.%06d secs\n", ops->count, (long)ops->bytes, - (int)(ops->msecs/1000), (int)(ops->msecs%1000)); + (int)(ops->usecs/usec_scale), (int)(ops->usecs%usec_scale)); /*@switchbreak@*/ break; case FDSTAT_SEEK: /*@switchbreak@*/ break; diff --git a/rpmio/rpmsq.c b/rpmio/rpmsq.c index fafa0d6..94dd4d0 100644 --- a/rpmio/rpmsq.c +++ b/rpmio/rpmsq.c @@ -296,10 +296,12 @@ fprintf(stderr, " Parent(%p): %p child %d\n", ME(), sq, sq->child); /*@=modfilesys@*/ #endif +#ifdef DYING /* Unblock child. */ xx = close(sq->pipes[0]); xx = close(sq->pipes[1]); sq->pipes[0] = sq->pipes[1] = -1; +#endif } @@ -323,6 +325,12 @@ static int rpmsqWaitUnregister(rpmsq sq) if (same_thread) ret = sighold(SIGCHLD); + if (sq->pipes[0] >= 0) + xx = close(sq->pipes[0]); + if (sq->pipes[1] >= 0) + xx = close(sq->pipes[1]); + sq->pipes[0] = sq->pipes[1] = -1; + /*@-infloops@*/ while (ret == 0 && sq->reaped != sq->child) { if (same_thread) { diff --git a/rpmio/rpmsw.c b/rpmio/rpmsw.c new file mode 100644 index 0000000..df944f0 --- /dev/null +++ b/rpmio/rpmsw.c @@ -0,0 +1,152 @@ +/** \ingroup rpmio + * \file rpmio/rpmsw.c + */ + +#include "system.h" +#include +#include "debug.h" + +/*@unchecked@*/ +static rpmtime_t rpmsw_overhead = 0; + +/*@unchecked@*/ +static rpmtime_t rpmsw_cycles = 1; + +/*@unchecked@*/ +static int rpmsw_type = 0; + +#if defined(__i386__) +static inline unsigned long long do_rdtsc ( void ) + /*@*/ +{ + unsigned long long x; + __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); + return x; +} +#endif + +rpmsw rpmswNow(rpmsw sw) +{ + static int oneshot = 0; + if (oneshot == 0) { + oneshot = 1; + rpmswInit(); + } + if (sw == NULL) + return NULL; + switch (rpmsw_type) { + case 0: + if (gettimeofday(&sw->u.tv, NULL)) + return NULL; + break; +#if defined(__i386__) + case 1: + sw->u.ticks = do_rdtsc(); + break; +#endif + } + return sw; +} + +/** \ingroup rpmio + * Return difference of 2 timeval stamps in micro-seconds. + * @param *etv end timeval + * @param *btv begin timeval + * @return difference in milli-seconds + */ +/*@unused@*/ static inline +rpmtime_t tvsub(/*@null@*/ const struct timeval * etv, + /*@null@*/ const struct timeval * btv) + /*@*/ +{ + rpmtime_t secs, usecs; + if (etv == NULL || btv == NULL) return 0; + secs = etv->tv_sec - btv->tv_sec; + for (usecs = etv->tv_usec - btv->tv_usec; usecs < 0; usecs += 1000000) + secs++; + return ((secs * 1000000) + usecs); +} + +rpmtime_t rpmswDiff(rpmsw end, rpmsw begin) +{ + rpmtime_t diff = 0; + + if (end == NULL || begin == NULL) + return 0; + switch (rpmsw_type) { + default: + case 0: + diff = tvsub(&end->u.tv, &begin->u.tv); + break; +#if defined(__i386__) + case 1: + if (end->u.ticks > begin->u.ticks) + diff = end->u.ticks - begin->u.ticks; + break; +#endif + } + if (diff >= rpmsw_overhead) + diff -= rpmsw_overhead; + if (rpmsw_cycles > 1) + diff /= rpmsw_cycles; + return diff; +} + +static rpmtime_t rpmswCalibrate(void) + /*@*/ +{ + struct rpmsw_s begin, end; + rpmtime_t ticks; + struct timespec req, rem; + int rc; + int i; + + (void) rpmswNow(&begin); + req.tv_sec = 0; + req.tv_nsec = 20 * 1000 * 1000; + for (i = 0; i < 100; i++) { + rc = nanosleep(&req, &rem); + if (rc == 0) + break; + if (rem.tv_sec == 0 && rem.tv_nsec == 0) + break; + req = rem; /* structure assignment */ + } + ticks = rpmswDiff(rpmswNow(&end), &begin); + + if (ticks < 1) + ticks = 1; + return ticks; +} + +rpmtime_t rpmswInit(void) +{ + struct rpmsw_s begin, end; + + rpmsw_type = 0; + rpmsw_overhead = 0; + rpmsw_cycles = 1; + +#if 0 + (void) rpmswNow(&begin); +#if defined(__i386) + rpmsw_type = 1; + rpmsw_cycles = rpmswCalibrate(); + rpmsw_type = 0; +#endif + rpmsw_overhead = rpmswDiff(rpmswNow(&end), &begin); +#if defined(__i386) + rpmsw_type = 1; + if (rpmsw_overhead > 1) + rpmsw_cycles /= rpmsw_overhead; +#endif + if (rpmsw_cycles < 1) + rpmsw_cycles = 1; +#endif + + rpmsw_overhead = 0; + (void) rpmswNow(&begin); + rpmsw_overhead = rpmswDiff(rpmswNow(&end), &begin); + + return rpmsw_overhead; +} diff --git a/rpmio/rpmsw.h b/rpmio/rpmsw.h new file mode 100644 index 0000000..677a562 --- /dev/null +++ b/rpmio/rpmsw.h @@ -0,0 +1,55 @@ +#ifndef H_RPMSW +#define H_RPMSW + +/** \ingroup rpmio + * \file rpmio/rpmsw.h + */ + +/** \ingroup rpmio + */ +typedef unsigned long rpmtime_t; + +/** \ingroup rpmio + */ +typedef struct rpmsw_s * rpmsw; + +/** \ingroup rpmio + */ +struct rpmsw_s { + union { + struct timeval tv; + unsigned long long ticks; + } u; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/** Return benchmark time stamp. + * @param *sw time stamp + * @return 0 on success + */ +/*@null@*/ +rpmsw rpmswNow(/*@returned@*/ rpmsw sw) + /*@modifies sw @*/; + +/** Return benchmark time stamp difference. + * @param *end end time stamp + * @param *begin begin time stamp + * @return difference in micro-seconds + */ +rpmtime_t rpmswDiff(/*@null@*/ rpmsw end, /*@null@*/ rpmsw begin) + /*@*/; + +/** Return benchmark time stamp overhead. + * @return overhead in micro-seconds + */ +rpmtime_t rpmswInit(void) + /*@*/; + +#ifdef __cplusplus +} +#endif + +#endif /* H_RPMIO_INTERNAL */