From f60ec855de0d6bfd29325fcb73b2901780e72e3d Mon Sep 17 00:00:00 2001 From: jbj Date: Mon, 7 Apr 2003 12:05:35 +0000 Subject: [PATCH] Calibrated stopwatch using rdtsc. Probes for digest/signature and rpmdb. CVS patchset: 6734 CVS date: 2003/04/07 12:05:35 --- lib/depends.c | 8 +++--- lib/fsm.c | 13 ++++++++- lib/package.c | 5 ++++ lib/psm.c | 22 +++++++++++---- lib/rpmts.c | 52 +++++++++++++++++++++++++--------- lib/rpmts.h | 29 +++++++++++-------- lib/signature.c | 14 ++++++++++ lib/transaction.c | 21 +++++++------- rpmdb/rpmdb.h | 29 ++++++++++++++++--- rpmio/rpmio_internal.h | 12 ++++++-- rpmio/rpmsq.c | 25 +++++++++++------ rpmio/rpmsq.h | 22 +++++++++++++-- rpmio/rpmsw.c | 75 +++++++++++++++++++++++++++++++------------------- rpmio/rpmsw.h | 20 +++++++++++++- 14 files changed, 256 insertions(+), 91 deletions(-) diff --git a/lib/depends.c b/lib/depends.c index bfe02be..9fdbfa7 100644 --- a/lib/depends.c +++ b/lib/depends.c @@ -1179,7 +1179,7 @@ int rpmtsOrder(rpmts ts) rpmalMakeIndex(ts->addedPackages); #endif - (void) rpmswEnter(&ts->op, -1); + (void) rpmswEnter(&ts->op_order, 0); /* T1. Initialize. */ if (oType == 0) @@ -1582,7 +1582,7 @@ assert(newOrderCount == ts->orderCount); #endif freeBadDeps(); - ts->ms_order += rpmswExit(&ts->op, -1)/1000; + (void) rpmswExit(&ts->op_order, 0); return 0; } @@ -1597,7 +1597,7 @@ int rpmtsCheck(rpmts ts) int xx; int rc; - (void) rpmswEnter(&ts->op, -1); + (void) rpmswEnter(&ts->op_check, 0); /* Do lazy, readonly, open of rpm database. */ if (rpmtsGetRdb(ts) == NULL && ts->dbmode != -1) { @@ -1724,7 +1724,7 @@ exit: mi = rpmdbFreeIterator(mi); pi = rpmtsiFree(pi); - ts->ms_check += rpmswExit(&ts->op, -1)/1000; + rpmswExit(&ts->op_check, 0); /*@-branchstate@*/ if (closeatexit) diff --git a/lib/fsm.c b/lib/fsm.c index edb6e9f..5618dc8 100644 --- a/lib/fsm.c +++ b/lib/fsm.c @@ -18,6 +18,7 @@ #define _RPMFI_INTERNAL #include "rpmfi.h" #include "rpmte.h" +#define _RPMTS_INTERNAL #include "rpmts.h" #include "rpmsq.h" @@ -405,7 +406,7 @@ int fsmNext(FSM_t fsm, fileStage nstage) { fsm->nstage = nstage; if (_fsm_threads) - return rpmsqThread(fsmThread, fsm); + return rpmsqJoin( rpmsqThread(fsmThread, fsm) ); return fsmStage(fsm, fsm->nstage); } @@ -2302,6 +2303,11 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break; if (fsm->rfd != NULL) { if (_fsm_debug && (stage & FSM_SYSCALL)) rpmMessage(RPMMESS_DEBUG, " %8s (%p)\n", cur, fsm->rfd); + if (fsm->rfd->stats != NULL) { + FDSTAT_t stats = fsm->rfd->stats; + rpmts ts = fsmGetTs(fsm); + (void) rpmswAdd(&ts->op_digest, &stats->ops[FDSTAT_DIGEST]); + } (void) Fclose(fsm->rfd); errno = saveerrno; } @@ -2330,6 +2336,11 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break; if (fsm->wfd != NULL) { if (_fsm_debug && (stage & FSM_SYSCALL)) rpmMessage(RPMMESS_DEBUG, " %8s (%p)\n", cur, fsm->wfd); + if (fsm->wfd->stats != NULL) { + FDSTAT_t stats = fsm->wfd->stats; + rpmts ts = fsmGetTs(fsm); + (void) rpmswAdd(&ts->op_digest, &stats->ops[FDSTAT_DIGEST]); + } (void) Fclose(fsm->wfd); errno = saveerrno; } diff --git a/lib/package.c b/lib/package.c index ef9949d..5871629 100644 --- a/lib/package.c +++ b/lib/package.c @@ -9,6 +9,7 @@ #include #include +#define _RPMTS_INTERNAL #include "rpmts.h" #include "misc.h" /* XXX stripTrailingChar() */ @@ -542,6 +543,7 @@ verifyinfo_exit: ildl[1] = (regionEnd - dataStart); ildl[1] = htonl(ildl[1]); + (void) rpmswEnter(&ts->op_digest, 0); dig->hdrmd5ctx = rpmDigestInit(PGPHASHALGO_MD5, RPMDIGEST_NONE); b = (unsigned char *) header_magic; @@ -563,6 +565,7 @@ verifyinfo_exit: nb = htonl(ildl[1]); (void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb); dig->nbytes += nb; + (void) rpmswExit(&ts->op_digest, dig->nbytes); break; #endif @@ -585,6 +588,7 @@ verifyinfo_exit: ildl[1] = htonl(ildl[1]); /*@=boundswrite@*/ + (void) rpmswEnter(&ts->op_digest, 0); dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE); b = (unsigned char *) header_magic; @@ -606,6 +610,7 @@ verifyinfo_exit: nb = htonl(ildl[1]); (void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb); dig->nbytes += nb; + (void) rpmswExit(&ts->op_digest, dig->nbytes); break; default: diff --git a/lib/psm.c b/lib/psm.c index 5a2a1cf..f0f77d2 100644 --- a/lib/psm.c +++ b/lib/psm.c @@ -474,7 +474,7 @@ static pid_t psmWait(rpmpsm psm) (void) rpmsqWait(&psm->sq); msecs = psm->sq.op.usecs/1000; - ts->ms_scriptlets += msecs; + (void) rpmswAdd(&ts->op_scriptlets, &psm->sq.op); rpmMessage(RPMMESS_DEBUG, _("%s: waitpid(%d) rc %d status %x secs %u.%03u\n"), @@ -1161,7 +1161,7 @@ static int rpmpsmNext(rpmpsm psm, pkgStage nstage) { psm->nstage = nstage; if (_psm_threads) - return rpmsqThread(rpmpsmThread, psm); + return rpmsqJoin( rpmsqThread(rpmpsmThread, psm) ); return rpmpsmStage(psm, psm->nstage); } @@ -1517,8 +1517,11 @@ psm->te->h = headerLink(fi->h); rc = fsmSetup(fi->fsm, FSM_PKGINSTALL, ts, fi, psm->cfd, NULL, &psm->failedFile); - if (psm->cfd->stats != NULL) - ts->ms_uncompress += psm->cfd->stats->ops[FDSTAT_READ].usecs/1000; + if (psm->cfd->stats != NULL) { + FDSTAT_t stats = psm->cfd->stats; + (void) rpmswAdd(&ts->op_uncompress, &stats->ops[FDSTAT_READ]); + (void) rpmswAdd(&ts->op_digest, &stats->ops[FDSTAT_DIGEST]); + } xx = fsmTeardown(fi->fsm); saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */ @@ -1598,8 +1601,11 @@ psm->te->h = headerLink(fi->h); rc = fsmSetup(fi->fsm, FSM_PKGBUILD, ts, fi, psm->cfd, NULL, &psm->failedFile); - if (psm->cfd->stats != NULL) - ts->ms_compress += psm->cfd->stats->ops[FDSTAT_WRITE].usecs/1000; + if (psm->cfd->stats != NULL) { + FDSTAT_t stats = psm->cfd->stats; + (void) rpmswAdd(&ts->op_uncompress, &stats->ops[FDSTAT_WRITE]); + (void) rpmswAdd(&ts->op_digest, &stats->ops[FDSTAT_DIGEST]); + } xx = fsmTeardown(fi->fsm); saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */ @@ -1879,17 +1885,21 @@ assert(psm->mi == NULL); case PSM_RPMDB_ADD: if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break; if (fi->h == NULL) break; /* XXX can't happen */ + (void) rpmswEnter(&ts->op_dbadd, 0); if (!(rpmtsVSFlags(ts) & RPMVSF_NOHDRCHK)) rc = rpmdbAdd(rpmtsGetRdb(ts), rpmtsGetTid(ts), fi->h, ts, headerCheck); else rc = rpmdbAdd(rpmtsGetRdb(ts), rpmtsGetTid(ts), fi->h, NULL, NULL); + (void) rpmswExit(&ts->op_dbadd, 0); break; case PSM_RPMDB_REMOVE: if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) break; + (void) rpmswEnter(&ts->op_dbremove, 0); rc = rpmdbRemove(rpmtsGetRdb(ts), rpmtsGetTid(ts), fi->record, NULL, NULL); + (void) rpmswExit(&ts->op_dbremove, 0); break; default: diff --git a/lib/rpmts.c b/lib/rpmts.c index 529c555..c56609f 100644 --- a/lib/rpmts.c +++ b/lib/rpmts.c @@ -133,6 +133,9 @@ int rpmtsCloseDB(rpmts ts) int rc = 0; if (ts->rdb != NULL) { + (void) rpmswAdd(&ts->op_dbget, &ts->rdb->db_getops); + (void) rpmswAdd(&ts->op_dbput, &ts->rdb->db_putops); + (void) rpmswAdd(&ts->op_dbdel, &ts->rdb->db_delops); rc = rpmdbClose(ts->rdb); ts->rdb = NULL; } @@ -313,6 +316,9 @@ int rpmtsCloseSDB(rpmts ts) int rc = 0; if (ts->sdb != NULL) { + (void) rpmswAdd(&ts->op_dbget, &ts->sdb->db_getops); + (void) rpmswAdd(&ts->op_dbput, &ts->sdb->db_putops); + (void) rpmswAdd(&ts->op_dbdel, &ts->sdb->db_delops); rc = rpmdbClose(ts->sdb); ts->sdb = NULL; } @@ -630,22 +636,42 @@ void rpmtsEmpty(rpmts ts) /*@=nullstate@*/ } -static void rpmtsPrintStats(rpmts ts) +static void rpmtsPrintStat(const char * name, struct rpmop_s * op) /*@globals fileSystem @*/ /*@modifies fileSystem @*/ { - rpmtime_t msecs = rpmswExit(&ts->create, -1)/1000; + static unsigned uscale = (1000 * 1000); + static unsigned mscale = (1024 * 1024); + if (op->count > 0) + fprintf(stderr, " %s %6d %6lu.%06lu MB %6lu.%06lu secs\n", + name, op->count, + (unsigned long)op->bytes/mscale, (unsigned long)op->bytes%mscale, + op->usecs/uscale, op->usecs%uscale); +} - fprintf(stderr, " total: %4lu.%03lu sec\n", msecs/1000, msecs%1000); - fprintf(stderr, " check: %4lu.%03lu sec\n", ts->ms_check/1000, ts->ms_check%1000); - fprintf(stderr, " order: %4lu.%03lu sec\n", ts->ms_order/1000, ts->ms_order%1000); - fprintf(stderr, " fingerprint: %4lu.%03lu sec\n", ts->ms_fingerprint/1000, ts->ms_fingerprint%1000); - fprintf(stderr, " repackage: %4lu.%03lu sec\n", ts->ms_repackage/1000, ts->ms_repackage%1000); - fprintf(stderr, " install: %4lu.%03lu sec\n", ts->ms_install/1000, ts->ms_install%1000); - fprintf(stderr, " erase: %4lu.%03lu sec\n", ts->ms_erase/1000, ts->ms_erase%1000); - fprintf(stderr, " scriptlets: %4lu.%03lu sec\n", ts->ms_scriptlets/1000, ts->ms_scriptlets%1000); - fprintf(stderr, " compress: %4lu.%03lu sec\n", ts->ms_compress/1000, ts->ms_compress%1000); - fprintf(stderr, " uncompress: %4lu.%03lu sec\n", ts->ms_uncompress/1000, ts->ms_uncompress%1000); +static void rpmtsPrintStats(rpmts ts) + /*@globals fileSystem @*/ + /*@modifies fileSystem @*/ +{ + (void) rpmswExit(&ts->op_total, 0); + + rpmtsPrintStat("total: ", &ts->op_total); + rpmtsPrintStat("check: ", &ts->op_check); + rpmtsPrintStat("order: ", &ts->op_order); + rpmtsPrintStat("fingerprint: ", &ts->op_fingerprint); + rpmtsPrintStat("repackage: ", &ts->op_repackage); + rpmtsPrintStat("install: ", &ts->op_install); + rpmtsPrintStat("erase: ", &ts->op_erase); + rpmtsPrintStat("scriptlets: ", &ts->op_scriptlets); + rpmtsPrintStat("compress: ", &ts->op_compress); + rpmtsPrintStat("uncompress: ", &ts->op_uncompress); + rpmtsPrintStat("digest: ", &ts->op_digest); + rpmtsPrintStat("signature: ", &ts->op_signature); + rpmtsPrintStat("dbadd: ", &ts->op_dbadd); + rpmtsPrintStat("dbremove: ", &ts->op_dbremove); + rpmtsPrintStat("dbget: ", &ts->op_dbget); + rpmtsPrintStat("dbput: ", &ts->op_dbput); + rpmtsPrintStat("dbdel: ", &ts->op_dbdel); } rpmts rpmtsFree(rpmts ts) @@ -1246,7 +1272,7 @@ rpmts rpmtsCreate(void) rpmts ts; ts = xcalloc(1, sizeof(*ts)); - rpmswEnter(&ts->create, -1); + (void) rpmswEnter(&ts->op_total, -1); ts->goal = TSM_UNKNOWN; ts->filesystemCount = 0; ts->filesystems = NULL; diff --git a/lib/rpmts.h b/lib/rpmts.h index fbdc88b..95ba0b8 100644 --- a/lib/rpmts.h +++ b/lib/rpmts.h @@ -196,18 +196,23 @@ struct rpmts_s { size_t pkpktlen; /*!< Current pubkey packet length. */ unsigned char pksignid[8]; /*!< Current pubkey fingerprint. */ - struct rpmop_s create; - struct rpmop_s op; /*!< Transaction operation time stamp. */ - - rpmtime_t ms_check; - rpmtime_t ms_order; - rpmtime_t ms_fingerprint; - rpmtime_t ms_repackage; - rpmtime_t ms_install; - rpmtime_t ms_erase; - rpmtime_t ms_scriptlets; - rpmtime_t ms_compress; - rpmtime_t ms_uncompress; + struct rpmop_s op_total; + struct rpmop_s op_check; + struct rpmop_s op_order; + struct rpmop_s op_fingerprint; + struct rpmop_s op_repackage; + struct rpmop_s op_install; + struct rpmop_s op_erase; + struct rpmop_s op_scriptlets; + struct rpmop_s op_compress; + struct rpmop_s op_uncompress; + struct rpmop_s op_digest; + struct rpmop_s op_signature; + struct rpmop_s op_dbadd; + struct rpmop_s op_dbremove; + struct rpmop_s op_dbget; + struct rpmop_s op_dbput; + struct rpmop_s op_dbdel; /*@null@*/ pgpDig dig; /*!< Current signature/pubkey parameters. */ diff --git a/lib/signature.c b/lib/signature.c index ca4d864..5fa6690 100644 --- a/lib/signature.c +++ b/lib/signature.c @@ -9,6 +9,7 @@ #include /* XXX for rpmGetPath() */ #include "rpmdb.h" +#define _RPMTS_INTERNAL #include "rpmts.h" #include "misc.h" /* XXX for dosetenv() and makeTempFile() */ @@ -1020,8 +1021,10 @@ verifyMD5Signature(const rpmts ts, /*@out@*/ char * t, goto exit; } + (void) rpmswEnter(&ts->op_digest, 0); (void) rpmDigestFinal(rpmDigestDup(md5ctx), (void **)&md5sum, &md5len, 0); + (void) rpmswExit(&ts->op_digest, 0); if (md5len != siglen || memcmp(md5sum, sig, md5len)) { res = RPMRC_FAIL; @@ -1076,8 +1079,10 @@ verifySHA1Signature(const rpmts ts, /*@out@*/ char * t, goto exit; } + (void) rpmswEnter(&ts->op_digest, 0); (void) rpmDigestFinal(rpmDigestDup(sha1ctx), (void **)&SHA1, NULL, 1); + (void) rpmswExit(&ts->op_digest, 0); if (SHA1 == NULL || strlen(SHA1) != strlen(sig) || strcmp(SHA1, sig)) { res = RPMRC_FAIL; @@ -1159,6 +1164,7 @@ verifyPGPSignature(rpmts ts, /*@out@*/ char * t, goto exit; } + (void) rpmswEnter(&ts->op_digest, 0); { DIGEST_CTX ctx = rpmDigestDup(md5ctx); byte signhash16[2]; const char * s; @@ -1179,6 +1185,7 @@ verifyPGPSignature(rpmts ts, /*@out@*/ char * t, #endif xx = rpmDigestFinal(ctx, (void **)&dig->md5, &dig->md5len, 1); + (void) rpmswExit(&ts->op_digest, sigp->hashlen); /* Compare leading 16 bits of digest for quick check. */ s = dig->md5; @@ -1217,10 +1224,12 @@ verifyPGPSignature(rpmts ts, /*@out@*/ char * t, if (res != RPMRC_OK) goto exit; + (void) rpmswEnter(&ts->op_signature, 0); if (rsavrfy(&dig->rsa_pk, &dig->rsahm, &dig->c)) res = RPMRC_OK; else res = RPMRC_FAIL; + (void) rpmswExit(&ts->op_signature, 0); exit: t = stpcpy(t, rpmSigString(res)); @@ -1277,9 +1286,11 @@ verifyGPGSignature(rpmts ts, /*@out@*/ char * t, goto exit; } + (void) rpmswEnter(&ts->op_digest, 0); { DIGEST_CTX ctx = rpmDigestDup(sha1ctx); byte signhash16[2]; + (void) rpmswEnter(&ts->op_digest, 0); if (sigp->hash != NULL) xx = rpmDigestUpdate(ctx, sigp->hash, sigp->hashlen); @@ -1295,6 +1306,7 @@ verifyGPGSignature(rpmts ts, /*@out@*/ char * t, } #endif xx = rpmDigestFinal(ctx, (void **)&dig->sha1, &dig->sha1len, 1); + (void) rpmswExit(&ts->op_digest, sigp->hashlen); mp32nzero(&dig->hm); mp32nsethex(&dig->hm, dig->sha1); @@ -1312,11 +1324,13 @@ verifyGPGSignature(rpmts ts, /*@out@*/ char * t, if (res != RPMRC_OK) goto exit; + (void) rpmswEnter(&ts->op_signature, 0); if (dsavrfy(&dig->p, &dig->q, &dig->g, &dig->hm, &dig->y, &dig->r, &dig->s)) res = RPMRC_OK; else res = RPMRC_FAIL; + (void) rpmswExit(&ts->op_signature, 0); exit: t = stpcpy(t, rpmSigString(res)); diff --git a/lib/transaction.c b/lib/transaction.c index 0e24d5d..a93757e 100644 --- a/lib/transaction.c +++ b/lib/transaction.c @@ -1154,8 +1154,6 @@ rpmMessage(RPMMESS_DEBUG, _("sanity checking %d elements\n"), rpmtsNElements(ts) */ rpmMessage(RPMMESS_DEBUG, _("computing %d file fingerprints\n"), totalFileCount); - (void) rpmswEnter(&ts->op, -1); - numAdded = numRemoved = 0; pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, 0)) != NULL) { @@ -1211,6 +1209,7 @@ rpmMessage(RPMMESS_DEBUG, _("computing %d file fingerprints\n"), totalFileCount) continue; /* XXX can't happen */ fc = rpmfiFC(fi); + (void) rpmswEnter(&ts->op_fingerprint, 0); fpLookupList(fpc, fi->dnl, fi->bnl, fi->dil, fc, fi->fps); /*@-branchstate@*/ fi = rpmfiInit(fi, 0); @@ -1223,6 +1222,8 @@ rpmMessage(RPMMESS_DEBUG, _("computing %d file fingerprints\n"), totalFileCount) /*@=dependenttrans@*/ } /*@=branchstate@*/ + (void) rpmswExit(&ts->op_fingerprint, fc); + } pi = rpmtsiFree(pi); @@ -1251,6 +1252,7 @@ rpmMessage(RPMMESS_DEBUG, _("computing file dispositions\n")); if (fc == 0) continue; + (void) rpmswEnter(&ts->op_fingerprint, 0); /* Extract file info for all files in this package from the database. */ matches = xcalloc(fc, sizeof(*matches)); if (rpmdbFindFpList(rpmtsGetRdb(ts), fi->fps, matches, fc)) { @@ -1350,6 +1352,7 @@ rpmMessage(RPMMESS_DEBUG, _("computing file dispositions\n")); case TR_REMOVED: /*@switchbreak@*/ break; } + (void) rpmswExit(&ts->op_fingerprint, fc); } pi = rpmtsiFree(pi); ps = rpmpsFree(ps); @@ -1367,8 +1370,6 @@ rpmMessage(RPMMESS_DEBUG, _("computing file dispositions\n")); NOTIFY(ts, (NULL, RPMCALLBACK_TRANS_STOP, 6, ts->orderCount, NULL, ts->notifyData)); - ts->ms_fingerprint += rpmswExit(&ts->op, totalFileCount)/1000; - /* =============================================== * Free unused memory as soon as possible. */ @@ -1424,7 +1425,7 @@ rpmMessage(RPMMESS_DEBUG, _("computing file dispositions\n")); numRemoved, NULL, ts->notifyData)); progress++; - (void) rpmswEnter(&ts->op, -1); + (void) rpmswEnter(&ts->op_repackage, 0); /* XXX TR_REMOVED needs CPIO_MAP_{ABSOLUTE,ADDDOT} CPIO_ALL_HARDLINKS */ fi->mapflags |= CPIO_MAP_ABSOLUTE; @@ -1437,7 +1438,7 @@ rpmMessage(RPMMESS_DEBUG, _("computing file dispositions\n")); fi->mapflags &= ~CPIO_MAP_ADDDOT; fi->mapflags &= ~CPIO_ALL_HARDLINKS; - ts->ms_repackage += rpmswExit(&ts->op, -1)/1000; + (void) rpmswExit(&ts->op_repackage, 0); /*@switchbreak@*/ break; } @@ -1472,7 +1473,7 @@ assert(psm != NULL); switch (rpmteType(p)) { case TR_ADDED: - (void) rpmswEnter(&ts->op, -1); + (void) rpmswEnter(&ts->op_install, 0); pkgKey = rpmteAddedKey(p); @@ -1569,12 +1570,12 @@ assert(psm != NULL); p->h = headerFree(p->h); - ts->ms_install += rpmswExit(&ts->op, -1)/1000; + (void) rpmswExit(&ts->op_install, 0); /*@switchbreak@*/ break; case TR_REMOVED: - (void) rpmswEnter(&ts->op, -1); + (void) rpmswEnter(&ts->op_erase, 0); rpmMessage(RPMMESS_DEBUG, "========== --- %s\n", rpmteNEVR(p)); /* @@ -1586,7 +1587,7 @@ assert(psm != NULL); ourrc++; } - ts->ms_erase += rpmswExit(&ts->op, -1)/1000; + (void) rpmswExit(&ts->op_erase, 0); /*@switchbreak@*/ break; } diff --git a/rpmdb/rpmdb.h b/rpmdb/rpmdb.h index 7b242c7..2affb46 100644 --- a/rpmdb/rpmdb.h +++ b/rpmdb/rpmdb.h @@ -9,6 +9,7 @@ #include #include "rpmlib.h" +#include "rpmsw.h" #include "db.h" /*@-exportlocal@*/ @@ -428,6 +429,10 @@ struct rpmdb_s { int db_ndbi; /*!< No. of tag indices. */ dbiIndex * _dbi; /*!< Tag indices. */ + struct rpmop_s db_getops; + struct rpmop_s db_putops; + struct rpmop_s db_delops; + /*@refs@*/ int nrefs; /*!< Reference count. */ }; @@ -557,8 +562,12 @@ int dbiDel(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data, /*@globals fileSystem @*/ /*@modifies *dbcursor, fileSystem @*/ { + int rc; assert(key->data != NULL && key->size > 0); - return (dbi->dbi_vec->cdel) (dbi, dbcursor, key, data, flags); + (void) rpmswEnter(&dbi->dbi_rpmdb->db_delops, 0); + rc = (dbi->dbi_vec->cdel) (dbi, dbcursor, key, data, flags); + (void) rpmswExit(&dbi->dbi_rpmdb->db_delops, data->size); + return rc; } /** \ingroup dbi @@ -576,8 +585,12 @@ int dbiGet(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data, /*@globals fileSystem @*/ /*@modifies *dbcursor, *key, *data, fileSystem @*/ { + int rc; assert((flags == DB_NEXT) || (key->data != NULL && key->size > 0)); - return (dbi->dbi_vec->cget) (dbi, dbcursor, key, data, flags); + (void) rpmswEnter(&dbi->dbi_rpmdb->db_getops, 0); + rc = (dbi->dbi_vec->cget) (dbi, dbcursor, key, data, flags); + (void) rpmswExit(&dbi->dbi_rpmdb->db_getops, data->size); + return rc; } /** \ingroup dbi @@ -596,8 +609,12 @@ int dbiPget(dbiIndex dbi, /*@null@*/ DBC * dbcursor, /*@globals fileSystem @*/ /*@modifies *dbcursor, *key, *pkey, *data, fileSystem @*/ { + int rc; assert((flags == DB_NEXT) || (key->data != NULL && key->size > 0)); - return (dbi->dbi_vec->cpget) (dbi, dbcursor, key, pkey, data, flags); + (void) rpmswEnter(&dbi->dbi_rpmdb->db_getops, 0); + rc = (dbi->dbi_vec->cpget) (dbi, dbcursor, key, pkey, data, flags); + (void) rpmswExit(&dbi->dbi_rpmdb->db_getops, data->size); + return rc; } /** \ingroup dbi @@ -615,8 +632,12 @@ int dbiPut(dbiIndex dbi, /*@null@*/ DBC * dbcursor, DBT * key, DBT * data, /*@globals fileSystem @*/ /*@modifies *dbcursor, *key, fileSystem @*/ { + int rc; assert(key->data != NULL && key->size > 0 && data->data != NULL && data->size > 0); - return (dbi->dbi_vec->cput) (dbi, dbcursor, key, data, flags); + (void) rpmswEnter(&dbi->dbi_rpmdb->db_putops, 0); + rc = (dbi->dbi_vec->cput) (dbi, dbcursor, key, data, flags); + (void) rpmswExit(&dbi->dbi_rpmdb->db_putops, data->size); + return rc; } /** \ingroup dbi diff --git a/rpmio/rpmio_internal.h b/rpmio/rpmio_internal.h index 26014d9..2be3ceb 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 e676857..1c2536c 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 40b8290..3ad5eb1 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 d96954a..b51a3dc 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 6ed42e5..8bcedf2 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 } -- 2.7.4