File: test_time.cc

package info (click to toggle)
mpich 4.3.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 101,184 kB
  • sloc: ansic: 1,040,629; cpp: 82,270; javascript: 40,763; perl: 27,933; python: 16,041; sh: 14,676; xml: 14,418; f90: 12,916; makefile: 9,270; fortran: 8,046; java: 4,635; asm: 324; ruby: 103; awk: 27; lisp: 19; php: 8; sed: 4
file content (145 lines) | stat: -rw-r--r-- 4,703 bytes parent folder | download | duplicates (6)
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);
    }
}