diff options
Diffstat (limited to 'rpmio/rpmsw.c')
-rw-r--r-- | rpmio/rpmsw.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/rpmio/rpmsw.c b/rpmio/rpmsw.c new file mode 100644 index 0000000..2a6d70a --- /dev/null +++ b/rpmio/rpmsw.c @@ -0,0 +1,131 @@ +/** \ingroup rpmio + * \file rpmio/rpmsw.c + */ + +#include "system.h" +#include <rpm/rpmsw.h> +#include "debug.h" + +static rpmtime_t rpmsw_overhead = 0; + +static rpmtime_t rpmsw_cycles = 1; + +static int rpmsw_initialized = 0; + +rpmsw rpmswNow(rpmsw sw) +{ + if (!rpmsw_initialized) + (void) rpmswInit(); + if (sw == NULL) + return NULL; + if (gettimeofday(&sw->u.tv, NULL)) + return NULL; + 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 + */ +static inline +rpmtime_t tvsub(const struct timeval * etv, + 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 * 1000000) + usecs); +} + +rpmtime_t rpmswDiff(rpmsw end, rpmsw begin) +{ + unsigned long long ticks = 0; + + if (end == NULL || begin == NULL) + return 0; + ticks = tvsub(&end->u.tv, &begin->u.tv); + if (ticks >= rpmsw_overhead) + ticks -= rpmsw_overhead; + if (rpmsw_cycles > 1) + ticks /= rpmsw_cycles; + return ticks; +} + +rpmtime_t rpmswInit(void) +{ + struct rpmsw_s begin, end; + rpmtime_t sum_overhead = 0; + int i; + + rpmsw_initialized = 1; + + rpmsw_overhead = 0; + rpmsw_cycles = 0; + + /* Convergence for simultaneous cycles and overhead is overkill ... */ + for (i = 0; i < 3; i++) { + /* Calculate timing overhead in usecs. */ + (void) rpmswNow(&begin); + sum_overhead += rpmswDiff(rpmswNow(&end), &begin); + + rpmsw_overhead = sum_overhead/(i+1); + } + + return rpmsw_overhead; +} + +int rpmswEnter(rpmop op, ssize_t rc) +{ + if (op == NULL) + return 0; + + op->count++; + if (rc < 0) { + op->bytes = 0; + op->usecs = 0; + } + (void) rpmswNow(&op->begin); + return 0; +} + +rpmtime_t rpmswExit(rpmop op, ssize_t rc) +{ + struct rpmsw_s end; + + if (op == NULL) + return 0; + + op->usecs += rpmswDiff(rpmswNow(&end), &op->begin); + if (rc > 0) + op->bytes += rc; + op->begin = end; /* structure assignment */ + return op->usecs; +} + +rpmtime_t rpmswAdd(rpmop to, rpmop from) +{ + rpmtime_t usecs = 0; + if (to != NULL && from != NULL) { + to->count += from->count; + to->bytes += from->bytes; + to->usecs += from->usecs; + usecs = to->usecs; + } + return usecs; +} + +rpmtime_t rpmswSub(rpmop to, rpmop from) +{ + rpmtime_t usecs = 0; + if (to != NULL && from != NULL) { + to->count -= from->count; + to->bytes -= from->bytes; + to->usecs -= from->usecs; + usecs = to->usecs; + } + return usecs; +} |