Flesh out time_*() API.

This commit is contained in:
Jason Evans
2016-02-19 12:35:37 -08:00
parent e5d5a4a517
commit 94451d184b
8 changed files with 397 additions and 56 deletions

View File

@@ -94,6 +94,7 @@
# define JEMALLOC_H_STRUCTS
# define JEMALLOC_H_EXTERNS
# define JEMALLOC_H_INLINES
# include "jemalloc/internal/time.h"
# include "jemalloc/internal/util.h"
# include "jemalloc/internal/qr.h"
# include "jemalloc/internal/ql.h"

View File

@@ -3,21 +3,9 @@
#include <unistd.h>
#include <sys/time.h>
#define JEMALLOC_CLOCK_GETTIME defined(_POSIX_MONOTONIC_CLOCK) \
&& _POSIX_MONOTONIC_CLOCK >= 0
typedef struct {
#ifdef _WIN32
FILETIME ft0;
FILETIME ft1;
#elif JEMALLOC_CLOCK_GETTIME
struct timespec ts0;
struct timespec ts1;
int clock_id;
#else
struct timeval tv0;
struct timeval tv1;
#endif
struct timespec t0;
struct timespec t1;
} timedelta_t;
void timer_start(timedelta_t *timer);

View File

@@ -4,50 +4,26 @@ void
timer_start(timedelta_t *timer)
{
#ifdef _WIN32
GetSystemTimeAsFileTime(&timer->ft0);
#elif JEMALLOC_CLOCK_GETTIME
if (sysconf(_SC_MONOTONIC_CLOCK) <= 0)
timer->clock_id = CLOCK_REALTIME;
else
timer->clock_id = CLOCK_MONOTONIC;
clock_gettime(timer->clock_id, &timer->ts0);
#else
gettimeofday(&timer->tv0, NULL);
#endif
time_init(&timer->t0, 0, 0);
time_update(&timer->t0);
}
void
timer_stop(timedelta_t *timer)
{
#ifdef _WIN32
GetSystemTimeAsFileTime(&timer->ft0);
#elif JEMALLOC_CLOCK_GETTIME
clock_gettime(timer->clock_id, &timer->ts1);
#else
gettimeofday(&timer->tv1, NULL);
#endif
time_copy(&timer->t1, &timer->t0);
time_update(&timer->t1);
}
uint64_t
timer_usec(const timedelta_t *timer)
{
struct timespec delta;
#ifdef _WIN32
uint64_t t0, t1;
t0 = (((uint64_t)timer->ft0.dwHighDateTime) << 32) |
timer->ft0.dwLowDateTime;
t1 = (((uint64_t)timer->ft1.dwHighDateTime) << 32) |
timer->ft1.dwLowDateTime;
return ((t1 - t0) / 10);
#elif JEMALLOC_CLOCK_GETTIME
return (((timer->ts1.tv_sec - timer->ts0.tv_sec) * 1000000) +
(timer->ts1.tv_nsec - timer->ts0.tv_nsec) / 1000);
#else
return (((timer->tv1.tv_sec - timer->tv0.tv_sec) * 1000000) +
timer->tv1.tv_usec - timer->tv0.tv_usec);
#endif
time_copy(&delta, &timer->t1);
time_subtract(&delta, &timer->t0);
return (time_sec(&delta) * 1000000 + time_nsec(&delta) / 1000);
}
void

View File

@@ -1,16 +1,206 @@
#include "test/jemalloc_test.h"
#define BILLION 1000000000
TEST_BEGIN(test_time_init)
{
struct timespec ts;
time_init(&ts, 42, 43);
assert_ld_eq(ts.tv_sec, 42, "tv_sec incorrectly initialized");
assert_ld_eq(ts.tv_nsec, 43, "tv_nsec incorrectly initialized");
}
TEST_END
TEST_BEGIN(test_time_sec)
{
struct timespec ts;
time_init(&ts, 42, 43);
assert_ld_eq(time_sec(&ts), 42, "tv_sec incorrectly read");
}
TEST_END
TEST_BEGIN(test_time_nsec)
{
struct timespec ts;
time_init(&ts, 42, 43);
assert_ld_eq(time_nsec(&ts), 43, "tv_nsec incorrectly read");
}
TEST_END
TEST_BEGIN(test_time_copy)
{
struct timespec tsa, tsb;
time_init(&tsa, 42, 43);
time_init(&tsb, 0, 0);
time_copy(&tsb, &tsa);
assert_ld_eq(time_sec(&tsb), 42, "tv_sec incorrectly copied");
assert_ld_eq(time_nsec(&tsb), 43, "tv_nsec incorrectly copied");
}
TEST_END
TEST_BEGIN(test_time_compare)
{
struct timespec tsa, tsb;
time_init(&tsa, 42, 43);
time_copy(&tsb, &tsa);
assert_d_eq(time_compare(&tsa, &tsb), 0, "Times should be equal");
assert_d_eq(time_compare(&tsb, &tsa), 0, "Times should be equal");
time_init(&tsb, 42, 42);
assert_d_eq(time_compare(&tsa, &tsb), 1,
"tsa should be greater than tsb");
assert_d_eq(time_compare(&tsb, &tsa), -1,
"tsb should be less than tsa");
time_init(&tsb, 42, 44);
assert_d_eq(time_compare(&tsa, &tsb), -1,
"tsa should be less than tsb");
assert_d_eq(time_compare(&tsb, &tsa), 1,
"tsb should be greater than tsa");
time_init(&tsb, 41, BILLION - 1);
assert_d_eq(time_compare(&tsa, &tsb), 1,
"tsa should be greater than tsb");
assert_d_eq(time_compare(&tsb, &tsa), -1,
"tsb should be less than tsa");
time_init(&tsb, 43, 0);
assert_d_eq(time_compare(&tsa, &tsb), -1,
"tsa should be less than tsb");
assert_d_eq(time_compare(&tsb, &tsa), 1,
"tsb should be greater than tsa");
}
TEST_END
TEST_BEGIN(test_time_add)
{
struct timespec tsa, tsb;
time_init(&tsa, 42, 43);
time_copy(&tsb, &tsa);
time_add(&tsa, &tsb);
time_init(&tsb, 84, 86);
assert_d_eq(time_compare(&tsa, &tsb), 0, "Incorrect addition result");
time_init(&tsa, 42, BILLION - 1);
time_copy(&tsb, &tsa);
time_add(&tsa, &tsb);
time_init(&tsb, 85, BILLION - 2);
assert_d_eq(time_compare(&tsa, &tsb), 0, "Incorrect addition result");
}
TEST_END
TEST_BEGIN(test_time_subtract)
{
struct timespec tsa, tsb;
time_init(&tsa, 42, 43);
time_copy(&tsb, &tsa);
time_subtract(&tsa, &tsb);
time_init(&tsb, 0, 0);
assert_d_eq(time_compare(&tsa, &tsb), 0,
"Incorrect subtraction result");
time_init(&tsa, 42, 43);
time_init(&tsb, 41, 44);
time_subtract(&tsa, &tsb);
time_init(&tsb, 0, BILLION - 1);
assert_d_eq(time_compare(&tsa, &tsb), 0,
"Incorrect subtraction result");
}
TEST_END
TEST_BEGIN(test_time_imultiply)
{
struct timespec tsa, tsb;
time_init(&tsa, 42, 43);
time_imultiply(&tsa, 10);
time_init(&tsb, 420, 430);
assert_d_eq(time_compare(&tsa, &tsb), 0,
"Incorrect multiplication result");
time_init(&tsa, 42, 666666666);
time_imultiply(&tsa, 3);
time_init(&tsb, 127, 999999998);
assert_d_eq(time_compare(&tsa, &tsb), 0,
"Incorrect multiplication result");
}
TEST_END
TEST_BEGIN(test_time_idivide)
{
struct timespec tsa, tsb;
time_init(&tsa, 42, 43);
time_copy(&tsb, &tsa);
time_imultiply(&tsa, 10);
time_idivide(&tsa, 10);
assert_d_eq(time_compare(&tsa, &tsb), 0, "Incorrect division result");
time_init(&tsa, 42, 666666666);
time_copy(&tsb, &tsa);
time_imultiply(&tsa, 3);
time_idivide(&tsa, 3);
assert_d_eq(time_compare(&tsa, &tsb), 0, "Incorrect division result");
}
TEST_END
TEST_BEGIN(test_time_divide)
{
struct timespec tsa, tsb, tsc;
time_init(&tsa, 42, 43);
time_copy(&tsb, &tsa);
time_imultiply(&tsa, 10);
assert_u64_eq(time_divide(&tsa, &tsb), 10,
"Incorrect division result");
time_init(&tsa, 42, 43);
time_copy(&tsb, &tsa);
time_imultiply(&tsa, 10);
time_init(&tsc, 0, 1);
time_add(&tsa, &tsc);
assert_u64_eq(time_divide(&tsa, &tsb), 10,
"Incorrect division result");
time_init(&tsa, 42, 43);
time_copy(&tsb, &tsa);
time_imultiply(&tsa, 10);
time_init(&tsc, 0, 1);
time_subtract(&tsa, &tsc);
assert_u64_eq(time_divide(&tsa, &tsb), 9, "Incorrect division result");
}
TEST_END
TEST_BEGIN(test_time_update)
{
struct timespec ts;
memset(&ts, 0, sizeof(struct timespec));
time_init(&ts, 0, 0);
assert_false(time_update(&ts), "Basic time update failed.");
/* Only Rip Van Winkle sleeps this long. */
ts.tv_sec += 631152000;
assert_true(time_update(&ts), "Update should detect time roll-back.");
{
struct timespec addend;
time_init(&addend, 631152000, 0);
time_add(&ts, &addend);
}
{
struct timespec ts0;
time_copy(&ts0, &ts);
assert_true(time_update(&ts),
"Update should detect time roll-back.");
assert_d_eq(time_compare(&ts, &ts0), 0,
"Time should not have been modified");
}
}
TEST_END
@@ -19,5 +209,15 @@ main(void)
{
return (test(
test_time_init,
test_time_sec,
test_time_nsec,
test_time_copy,
test_time_compare,
test_time_add,
test_time_subtract,
test_time_imultiply,
test_time_idivide,
test_time_divide,
test_time_update));
}