Skip to content

Commit

Permalink
cc: extend duration module (twitter#192)
Browse files Browse the repository at this point in the history
- add fast (low overhead) duration timers for linux
- add duration compare method
  • Loading branch information
michalbiesek authored and Yao Yue committed Jun 27, 2019
1 parent b117632 commit a64ada2
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 13 deletions.
23 changes: 22 additions & 1 deletion include/time/cc_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ struct duration; /* data structure to measure duration */
* relationship between this unit and nanosecond can be obtained via another
* syscall
*/

enum duration_type {
DURATION_PRECISE, /* default */
DURATION_FAST,

MAX_DURATION_TYPE
};

#ifdef OS_DARWIN
struct duration {
bool started;
Expand All @@ -58,6 +66,7 @@ struct duration {
};
#elif defined OS_LINUX
struct duration {
enum duration_type type;
bool started;
bool stopped;
struct timespec start;
Expand Down Expand Up @@ -86,19 +95,31 @@ struct timeout {
bool is_intvl;
};


/* update duration */
void duration_reset(struct duration *d);
/* get a reading of duration and copy it without stopping the original timer */
void duration_snapshot(struct duration *s, const struct duration *d);
void duration_start(struct duration *d);
void duration_start_type(struct duration *d, enum duration_type type);
void duration_stop(struct duration *d);
/* read duration */
double duration_ns(struct duration *d);
double duration_us(struct duration *d);
double duration_ms(struct duration *d);
double duration_sec(struct duration *d);

static inline int
duration_compare(const void *lhs, const void *rhs)
{
double lns = duration_ns((struct duration *)lhs);
double rns = duration_ns((struct duration *)rhs);
if (lns < rns)
return -1;
if (lns > rns)
return 1;

return 0;
}

/*
* Not all possible granularity can be meaningfully used for sleep or event.
Expand Down
6 changes: 6 additions & 0 deletions src/time/cc_timer_darwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ duration_start(struct duration *d)
d->start = mach_absolute_time();
}

void
duration_start_type(struct duration *d, enum duration_type type)
{
duration_start(d);
}

void
duration_stop(struct duration *d)
{
Expand Down
42 changes: 30 additions & 12 deletions src/time/cc_timer_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,35 @@
* CLOCK_REALTIME can be reset when clock has drifted, so it may not always be
* monotonic, and should be avoided if possible.
*/
static const clockid_t cid[MAX_DURATION_TYPE] = {
[DURATION_PRECISE] =
#if defined(CLOCK_MONOTONIC_RAW)
static const clockid_t cid = CLOCK_MONOTONIC_RAW;
CLOCK_MONOTONIC_RAW
#elif defined(CLOCK_MONOTONIC)
static const clockid_t cid = CLOCK_MONOTONIC;
CLOCK_MONOTONIC
#elif defined(CLOCK_REALTIME)
static const clockid_t cid = CLOCK_REALTIME;
CLOCK_REALTIME
#else
static const clockid_t cid = (clockid_t)-1;
(clockid_t)-1
#endif
,
#if defined(CLOCK_MONOTONIC)
CLOCK_MONOTONIC
#elif defined(CLOCK_REALTIME)
CLOCK_REALTIME
#else
(clockid_t)-1
#endif
};

static inline void
_gettime(struct timespec *ts)
_gettime(struct timespec *ts, enum duration_type type)
{
int ret;

ASSERT(cid != (clockid_t)-1);
ASSERT(cid[type] != (clockid_t)-1);

ret = clock_gettime(cid, ts);
ret = clock_gettime(cid[type], ts);
if (ret == -1) {
/*
* Note(yao): for the purpose of this module, it doesn't make much sense
Expand Down Expand Up @@ -73,10 +84,17 @@ duration_reset(struct duration *d)

void
duration_start(struct duration *d)
{
duration_start_type(d, DURATION_PRECISE);
}

void
duration_start_type(struct duration *d, enum duration_type type)
{
ASSERT(d != NULL);

_gettime(&d->start);
_gettime(&d->start, type);
d->type = type;
d->started = true;
}

Expand All @@ -87,16 +105,17 @@ duration_snapshot(struct duration *s, const struct duration *d)

s->started = true;
s->start = d->start;
s->type = d->type;
s->stopped = true;
_gettime(&s->stop);
_gettime(&s->stop, s->type);
}

void
duration_stop(struct duration *d)
{
ASSERT(d != NULL);

_gettime(&d->stop);
_gettime(&d->stop, d->type);
d->stopped = true;
}

Expand Down Expand Up @@ -153,9 +172,8 @@ _now_ns(void)
{
struct timespec now;

_gettime(&now);
_gettime(&now, cid[DURATION_PRECISE]);
return now.tv_sec * NSEC_PER_SEC + now.tv_nsec;

}

void
Expand Down

0 comments on commit a64ada2

Please sign in to comment.