Probes for digest/signature and rpmdb.
CVS patchset: 6734
CVS date: 2003/04/07 12:05:35
rpmalMakeIndex(ts->addedPackages);
#endif
- (void) rpmswEnter(&ts->op, -1);
+ (void) rpmswEnter(&ts->op_order, 0);
/* T1. Initialize. */
if (oType == 0)
#endif
freeBadDeps();
- ts->ms_order += rpmswExit(&ts->op, -1)/1000;
+ (void) rpmswExit(&ts->op_order, 0);
return 0;
}
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) {
mi = rpmdbFreeIterator(mi);
pi = rpmtsiFree(pi);
- ts->ms_check += rpmswExit(&ts->op, -1)/1000;
+ rpmswExit(&ts->op_check, 0);
/*@-branchstate@*/
if (closeatexit)
#define _RPMFI_INTERNAL
#include "rpmfi.h"
#include "rpmte.h"
+#define _RPMTS_INTERNAL
#include "rpmts.h"
#include "rpmsq.h"
{
fsm->nstage = nstage;
if (_fsm_threads)
- return rpmsqThread(fsmThread, fsm);
+ return rpmsqJoin( rpmsqThread(fsmThread, fsm) );
return fsmStage(fsm, fsm->nstage);
}
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;
}
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;
}
#include <rpmio_internal.h>
#include <rpmlib.h>
+#define _RPMTS_INTERNAL
#include "rpmts.h"
#include "misc.h" /* XXX stripTrailingChar() */
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;
nb = htonl(ildl[1]);
(void) rpmDigestUpdate(dig->hdrmd5ctx, b, nb);
dig->nbytes += nb;
+ (void) rpmswExit(&ts->op_digest, dig->nbytes);
break;
#endif
ildl[1] = htonl(ildl[1]);
/*@=boundswrite@*/
+ (void) rpmswEnter(&ts->op_digest, 0);
dig->hdrsha1ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
b = (unsigned char *) header_magic;
nb = htonl(ildl[1]);
(void) rpmDigestUpdate(dig->hdrsha1ctx, b, nb);
dig->nbytes += nb;
+ (void) rpmswExit(&ts->op_digest, dig->nbytes);
break;
default:
(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"),
{
psm->nstage = nstage;
if (_psm_threads)
- return rpmsqThread(rpmpsmThread, psm);
+ return rpmsqJoin( rpmsqThread(rpmpsmThread, psm) );
return rpmpsmStage(psm, psm->nstage);
}
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 */
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 */
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:
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;
}
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;
}
/*@=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)
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;
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. */
#include <rpmmacro.h> /* XXX for rpmGetPath() */
#include "rpmdb.h"
+#define _RPMTS_INTERNAL
#include "rpmts.h"
#include "misc.h" /* XXX for dosetenv() and makeTempFile() */
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;
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;
goto exit;
}
+ (void) rpmswEnter(&ts->op_digest, 0);
{ DIGEST_CTX ctx = rpmDigestDup(md5ctx);
byte signhash16[2];
const char * s;
#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;
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));
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);
}
#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);
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));
*/
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) {
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);
/*@=dependenttrans@*/
}
/*@=branchstate@*/
+ (void) rpmswExit(&ts->op_fingerprint, fc);
+
}
pi = rpmtsiFree(pi);
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)) {
case TR_REMOVED:
/*@switchbreak@*/ break;
}
+ (void) rpmswExit(&ts->op_fingerprint, fc);
}
pi = rpmtsiFree(pi);
ps = rpmpsFree(ps);
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.
*/
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;
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;
}
switch (rpmteType(p)) {
case TR_ADDED:
- (void) rpmswEnter(&ts->op, -1);
+ (void) rpmswEnter(&ts->op_install, 0);
pkgKey = rpmteAddedKey(p);
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));
/*
ourrc++;
}
- ts->ms_erase += rpmswExit(&ts->op, -1)/1000;
+ (void) rpmswExit(&ts->op_erase, 0);
/*@switchbreak@*/ break;
}
#include <assert.h>
#include "rpmlib.h"
+#include "rpmsw.h"
#include "db.h"
/*@-exportlocal@*/
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. */
};
/*@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
/*@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
/*@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
/*@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
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
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);
}
}
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);
}
}
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;
}
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);
}
/**
/*@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 @*/;
/*@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)
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)
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;
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;
(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);
}
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@*/
/*@=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@*/
*/
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
}