1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
/**
* Copyright (c) NVIDIA CORPORATION & AFFILIATES, 2001-2014. ALL RIGHTS RESERVED.
* Copyright (C) UT-Battelle, LLC. 2014. ALL RIGHTS RESERVED.
* Copyright (C) ARM Ltd. 2016. ALL RIGHTS RESERVED.
* See file LICENSE for terms.
*/
#include <common/test.h>
extern "C" {
#include <ucs/time/timerq.h>
}
#include <time.h>
class test_time : public ucs::test {
};
UCS_TEST_F(test_time, time_calc) {
double value = ucs::rand() % UCS_USEC_PER_SEC;
EXPECT_NEAR(value * 1000ull, ucs_time_to_msec(ucs_time_from_sec (value)), 0.000001);
EXPECT_NEAR(value * 1000ull, ucs_time_to_usec(ucs_time_from_msec(value)), 0.02);
EXPECT_NEAR(value * 1000ull, ucs_time_to_nsec(ucs_time_from_usec(value)), 20.0);
}
/* This test is only useful when used with high-precision timers */
#if HAVE_HW_TIMER
UCS_TEST_SKIP_COND_F(test_time, get_time,
(ucs::test_time_multiplier() > 1)) {
ucs_time_t time1 = ucs_get_time();
ucs_time_t time2 = ucs_get_time();
EXPECT_GE(time2, time1);
ucs_time_t start_time = ucs_get_time();
ucs_time_t end_time = start_time + ucs_time_from_sec(1);
ucs_time_t current_time;
time_t system_start_time = time(NULL);
uint64_t count = 0;
do {
current_time = ucs_get_time();
++count;
} while (current_time <= end_time);
/* Check the sleep interval is correct */
if (ucs::perf_retry_count) {
ASSERT_NEAR(1.0, time(NULL) - system_start_time, 1.00001);
double nsec = (ucs_time_to_nsec(current_time - start_time)) / count;
EXPECT_LT(nsec, 40.0) << "ucs_get_time() performance is too bad";
}
}
#endif
UCS_TEST_F(test_time, timerq) {
static const int TIMER_ID_1 = 100;
static const int TIMER_ID_2 = 200;
ucs_timer_queue_t timerq;
ucs_status_t status;
for (unsigned test_count = 0; test_count < 500; ++test_count) {
const ucs_time_t interval1 = (ucs::rand() % 20) + 1;
const ucs_time_t interval2 = (ucs::rand() % 20) + 1;
const ucs_time_t test_time = ucs::rand() % 10000;
const ucs_time_t time_base = ucs::rand();
ucs_timer_t *timer;
unsigned counter1, counter2;
status = ucs_timerq_init(&timerq);
ASSERT_UCS_OK(status);
EXPECT_TRUE(ucs_timerq_is_empty(&timerq));
EXPECT_EQ(UCS_TIME_INFINITY, ucs_timerq_min_interval(&timerq));
ucs_time_t current_time = time_base;
ucs_timerq_add(&timerq, TIMER_ID_1, interval1);
ucs_timerq_add(&timerq, TIMER_ID_2, interval2);
EXPECT_FALSE(ucs_timerq_is_empty(&timerq));
EXPECT_EQ(std::min(interval1, interval2), ucs_timerq_min_interval(&timerq));
/*
* Check that both timers are invoked
*/
counter1 = 0;
counter2 = 0;
for (unsigned count = 0; count < test_time; ++count) {
++current_time;
ucs_timerq_for_each_expired(timer, &timerq, current_time, {
if (timer->id == TIMER_ID_1) ++counter1;
if (timer->id == TIMER_ID_2) ++counter2;
})
}
EXPECT_NEAR(test_time / interval1, counter1, 1);
EXPECT_NEAR(test_time / interval2, counter2, 1);
/*
* Check that after canceling, only one timer is invoked
*/
counter1 = 0;
counter2 = 0;
status = ucs_timerq_remove(&timerq, TIMER_ID_1);
ASSERT_UCS_OK(status);
for (unsigned count = 0; count < test_time; ++count) {
++current_time;
ucs_timerq_for_each_expired(timer, &timerq, current_time, {
if (timer->id == TIMER_ID_1) ++counter1;
if (timer->id == TIMER_ID_2) ++counter2;
})
}
EXPECT_EQ(0u, counter1);
EXPECT_NEAR(test_time / interval2, counter2, 1);
EXPECT_EQ(interval2, ucs_timerq_min_interval(&timerq));
/*
* Check that after rescheduling, both timers are invoked again
*/
ucs_timerq_add(&timerq, TIMER_ID_1, interval1);
counter1 = 0;
counter2 = 0;
for (unsigned count = 0; count < test_time; ++count) {
++current_time;
ucs_timerq_for_each_expired(timer, &timerq, current_time, {
if (timer->id == TIMER_ID_1) ++counter1;
if (timer->id == TIMER_ID_2) ++counter2;
})
}
EXPECT_NEAR(test_time / interval1, counter1, 1);
EXPECT_NEAR(test_time / interval2, counter2, 1);
status = ucs_timerq_remove(&timerq, TIMER_ID_1);
ASSERT_UCS_OK(status);
status = ucs_timerq_remove(&timerq, TIMER_ID_2);
ASSERT_UCS_OK(status);
ucs_timerq_cleanup(&timerq);
}
}
|