rpm/rpmio/rpmsw.c

132 lines
2.6 KiB
C

/** \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;
}