Add benchmark stopwatch, change precision from milli- to micro-secs.
authorjbj <devnull@localhost>
Mon, 24 Mar 2003 17:25:42 +0000 (17:25 +0000)
committerjbj <devnull@localhost>
Mon, 24 Mar 2003 17:25:42 +0000 (17:25 +0000)
CVS patchset: 6715
CVS date: 2003/03/24 17:25:42

Doxyfile.in
configure.ac
po/POTFILES.in
rpmdb/header.c
rpmio/Makefile.am
rpmio/rpmio.c
rpmio/rpmio_internal.h
rpmio/rpmsq.c
rpmio/rpmsw.c [new file with mode: 0644]
rpmio/rpmsw.h [new file with mode: 0644]

index dffd9e0..9146b35 100644 (file)
@@ -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 \
index e41295d..3625759 100644 (file)
@@ -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                                                  *
 *                                                                          *
 ****************************************************************************
index b555022..4a6abf4 100644 (file)
@@ -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
index abae5e9..7d33522 100644 (file)
@@ -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
  */
index 6cb00ea..2400182 100644 (file)
@@ -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@ \
index 68a591f..684551d 100644 (file)
@@ -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;
index de2dd21..378e385 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <beecrypt/types.h>
 #include <rpmpgp.h>
+#include <rpmsw.h>
 
 /* Drag in the beecrypt includes. */
 #include <beecrypt/beecrypt.h>
@@ -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;
index fafa0d6..94dd4d0 100644 (file)
@@ -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 (file)
index 0000000..df944f0
--- /dev/null
@@ -0,0 +1,152 @@
+/** \ingroup rpmio
+ * \file rpmio/rpmsw.c
+ */
+
+#include "system.h"
+#include <rpmsw.h>
+#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 (file)
index 0000000..677a562
--- /dev/null
@@ -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 */