From f60ec855de0d6bfd29325fcb73b2901780e72e3d Mon Sep 17 00:00:00 2001 From: jbj Date: Mon, 7 Apr 2003 12:05:35 +0000 Subject: Calibrated stopwatch using rdtsc. Probes for digest/signature and rpmdb. CVS patchset: 6734 CVS date: 2003/04/07 12:05:35 --- rpmio/rpmio_internal.h | 12 ++++++-- rpmio/rpmsq.c | 25 +++++++++++------ rpmio/rpmsq.h | 22 +++++++++++++-- rpmio/rpmsw.c | 75 +++++++++++++++++++++++++++++++------------------- rpmio/rpmsw.h | 20 +++++++++++++- 5 files changed, 113 insertions(+), 41 deletions(-) (limited to 'rpmio') diff --git a/rpmio/rpmio_internal.h b/rpmio/rpmio_internal.h index 26014d9cc..2be3ceb8b 100644 --- a/rpmio/rpmio_internal.h +++ b/rpmio/rpmio_internal.h @@ -108,14 +108,16 @@ enum FDSTAT_e { FDSTAT_READ = 0, /*!< Read statistics index. */ FDSTAT_WRITE = 1, /*!< Write statistics index. */ FDSTAT_SEEK = 2, /*!< Seek statistics index. */ - FDSTAT_CLOSE = 3 /*!< Close statistics index */ + FDSTAT_CLOSE = 3, /*!< Close statistics index */ + FDSTAT_DIGEST = 4, /*!< Digest statistics index. */ + FDSTAT_MAX = 5 }; /** \ingroup rpmio * Cumulative statistics for a descriptor. */ typedef /*@abstract@*/ struct { - struct rpmop_s ops[4]; /*!< Cumulative statistics. */ + struct rpmop_s ops[FDSTAT_MAX]; /*!< Cumulative statistics. */ } * FDSTAT_t; /** \ingroup rpmio @@ -491,7 +493,9 @@ void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags) if (fddig != (fd->digests + FDDIGEST_MAX)) { fd->ndigests++; fddig->hashalgo = hashalgo; + fdstat_enter(fd, FDSTAT_DIGEST); fddig->hashctx = rpmDigestInit(hashalgo, flags); + fdstat_exit(fd, FDSTAT_DIGEST, 0); } } @@ -509,7 +513,9 @@ void fdUpdateDigests(FD_t fd, const unsigned char * buf, ssize_t buflen) FDDIGEST_t fddig = fd->digests + i; if (fddig->hashctx == NULL) continue; + fdstat_enter(fd, FDSTAT_DIGEST); (void) rpmDigestUpdate(fddig->hashctx, buf, buflen); + fdstat_exit(fd, FDSTAT_DIGEST, buflen); } } @@ -532,7 +538,9 @@ void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo, if (i > imax) imax = i; if (fddig->hashalgo != hashalgo) continue; + fdstat_enter(fd, FDSTAT_DIGEST); (void) rpmDigestFinal(fddig->hashctx, datap, lenp, asAscii); + fdstat_exit(fd, FDSTAT_DIGEST, 0); fddig->hashctx = NULL; break; } diff --git a/rpmio/rpmsq.c b/rpmio/rpmsq.c index e676857fa..1c2536ced 100644 --- a/rpmio/rpmsq.c +++ b/rpmio/rpmsq.c @@ -449,19 +449,28 @@ fprintf(stderr, " Fini(%p): %p child %d status 0x%x\n", ME(), sq, sq->child return sq->reaped; } -int rpmsqThread(void * (*start) (void * arg), void * arg) +void * rpmsqThread(void * (*start) (void * arg), void * arg) { pthread_t pth; int ret; ret = pthread_create(&pth, NULL, start, arg); - if (ret == 0) { -#if 0 -fprintf(stderr, " Thread(%p): %p\n", ME(), pth); -#endif - ret = pthread_join(pth, NULL); - } - return ret; + return (ret == 0 ? (void *)pth : NULL); +} + +int rpmsqJoin(void * thread) +{ + pthread_t pth = (pthread_t) thread; + if (thread == NULL) + return EINVAL; + return pthread_join(pth, NULL); +} + +int rpmsqThreadEqual(void * thread) +{ + pthread_t t1 = (pthread_t) thread; + pthread_t t2 = pthread_self(); + return pthread_equal(t1, t2); } /** diff --git a/rpmio/rpmsq.h b/rpmio/rpmsq.h index 40b829029..3ad5eb182 100644 --- a/rpmio/rpmsq.h +++ b/rpmio/rpmsq.h @@ -123,12 +123,30 @@ pid_t rpmsqWait(rpmsq sq) /*@modifies sq, fileSystem, internalState @*/; /** - * Call a function in a thread synchronously. + * Call a function in a thread. * @param start function * @param arg function argument + * @return thread pointer (NULL on error) + */ +void * rpmsqThread(void * (*start) (void * arg), void * arg) + /*@globals internalState @*/ + /*@modifies internalState @*/; + +/** + * Wait for thread to terminate. + * @param thread thread * @return 0 on success */ -int rpmsqThread(void * (*start) (void * arg), void * arg) +int rpmsqJoin(/*@null@*/ void * thread) + /*@globals internalState @*/ + /*@modifies internalState @*/; + +/** + * Compare thread with current thread. + * @param thread thread + * @return 0 if not equal + */ +int rpmsqThreadEqual(/*@null@*/ void * thread) /*@globals internalState @*/ /*@modifies internalState @*/; diff --git a/rpmio/rpmsw.c b/rpmio/rpmsw.c index d96954abf..b51a3dc1a 100644 --- a/rpmio/rpmsw.c +++ b/rpmio/rpmsw.c @@ -27,7 +27,7 @@ static int rpmsw_type = 0; /*@unchecked@*/ static int rpmsw_initialized = 0; -#if 0 /* XXX defined(__i386__) */ +#if defined(__i386__) /* Swiped from glibc-2.3.2 sysdeps/i386/i686/hp-timing.h */ #define HP_TIMING_ZERO(Var) (Var) = (0) @@ -114,33 +114,33 @@ rpmtime_t tvsub(/*@null@*/ const struct timeval * etv, 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++; + secs--; return ((secs * 1000000) + usecs); } rpmtime_t rpmswDiff(rpmsw end, rpmsw begin) { - rpmtime_t diff = 0; + unsigned long long ticks = 0; if (end == NULL || begin == NULL) return 0; switch (rpmsw_type) { default: case 0: - diff = tvsub(&end->u.tv, &begin->u.tv); + ticks = tvsub(&end->u.tv, &begin->u.tv); break; #if defined(HP_TIMING_NOW) case 1: if (end->u.ticks > begin->u.ticks) - HP_TIMING_DIFF(diff, begin->u.ticks, end->u.ticks); + HP_TIMING_DIFF(ticks, begin->u.ticks, end->u.ticks); break; #endif } - if (diff >= rpmsw_overhead) - diff -= rpmsw_overhead; + if (ticks >= rpmsw_overhead) + ticks -= rpmsw_overhead; if (rpmsw_cycles > 1) - diff /= rpmsw_cycles; - return diff; + ticks /= rpmsw_cycles; + return ticks; } #if defined(HP_TIMING_NOW) @@ -187,7 +187,10 @@ rpmtime_t rpmswInit(void) rpmsw_type @*/ { struct rpmsw_s begin, end; - rpmtime_t cycles, usecs; + unsigned long long sum_cycles = 0; + rpmtime_t sum_usecs = 0; + rpmtime_t sum_overhead = 0; + rpmtime_t cycles; int i; rpmsw_initialized = 1; @@ -195,8 +198,8 @@ rpmtime_t rpmswInit(void) rpmsw_overhead = 0; rpmsw_cycles = 0; - /* Convergence is futile overkill ... */ - for (i = 0; i < 1; i++) { + /* Convergence for simultaneous cycles and overhead is overkill ... */ + for (i = 0; i < 3; i++) { #if defined(HP_TIMING_NOW) rpmtime_t save_cycles = rpmsw_cycles; @@ -209,39 +212,31 @@ rpmtime_t rpmswInit(void) (void) rpmswNow(&begin); /*@=uniondef@*/ - /* Get no. of cycles in 20ms nanosleep */ + /* Get no. of cycles while doing nanosleep. */ rpmsw_type = 1; cycles = rpmswCalibrate(); - if (i) + if (save_cycles > 0 && rpmsw_overhead > 0) cycles -= (save_cycles * rpmsw_overhead); + sum_cycles += cycles; /* Compute wall clock delta in usecs. */ rpmsw_type = 0; /*@-uniondef@*/ - usecs = rpmswDiff(rpmswNow(&end), &begin); + sum_usecs += rpmswDiff(rpmswNow(&end), &begin); /*@=uniondef@*/ - rpmsw_type = 1; /* Compute cycles/usec */ - if (usecs > 1) - cycles /= usecs; - - rpmsw_cycles = save_cycles; - rpmsw_cycles *= i; - rpmsw_cycles += cycles; - rpmsw_cycles /= (i+1); + rpmsw_cycles = sum_cycles/sum_usecs; #endif /* Calculate timing overhead in usecs. */ /*@-uniondef@*/ (void) rpmswNow(&begin); - usecs = rpmswDiff(rpmswNow(&end), &begin); + sum_overhead += rpmswDiff(rpmswNow(&end), &begin); /*@=uniondef@*/ - rpmsw_overhead *= i; - rpmsw_overhead += usecs; - rpmsw_overhead /= (i+1); + rpmsw_overhead = sum_overhead/(i+1); } @@ -253,8 +248,10 @@ rpmtime_t rpmswInit(void) int rpmswEnter(rpmop op, ssize_t rc) { op->count++; - if (rc < 0) + if (rc < 0) { + op->bytes = 0; op->usecs = 0; + } /*@-uniondef@*/ (void) rpmswNow(&op->begin); /*@=uniondef@*/ @@ -270,6 +267,28 @@ rpmtime_t rpmswExit(rpmop op, ssize_t rc) /*@=uniondef@*/ if (rc > 0) op->bytes += rc; + op->begin = end; /* structure assignment */ return op->usecs; } + +rpmtime_t rpmswAdd(rpmop to, rpmop from) +{ + if (to != NULL && from != NULL) { + to->count += from->count; + to->bytes += from->bytes; + to->usecs += from->usecs; + } + return to->usecs; +} + +rpmtime_t rpmswSub(rpmop to, rpmop from) +{ + if (to != NULL && from != NULL) { + to->count -= from->count; + to->bytes -= from->bytes; + to->usecs -= from->usecs; + } + return to->usecs; +} + /*@=mods@*/ diff --git a/rpmio/rpmsw.h b/rpmio/rpmsw.h index 6ed42e58a..8bcedf274 100644 --- a/rpmio/rpmsw.h +++ b/rpmio/rpmsw.h @@ -89,7 +89,25 @@ int rpmswEnter(rpmop op, ssize_t rc) */ rpmtime_t rpmswExit(rpmop op, ssize_t rc) /*@globals internalState @*/ - /*@modifies *op, internalState @*/; + /*@modifies op, internalState @*/; + +/** \ingroup rpmio + * Sum statistic counters. + * @param to result statistics + * @param from operation statistics + * @return cumulative usecs for operation + */ +rpmtime_t rpmswAdd(rpmop to, rpmop from) + /*@modifies to @*/; + +/** \ingroup rpmio + * Subtract statistic counters. + * @param to result statistics + * @param from operation statistics + * @return cumulative usecs for operation + */ +rpmtime_t rpmswSub(rpmop to, rpmop from) + /*@modifies to @*/; #ifdef __cplusplus } -- cgit v1.2.3