fix overwrite of timer timeout when it matches previous time wheel position

This commit is contained in:
Francisco 2021-04-20 17:04:10 +01:00 committed by Francisco Paisana
parent 6d27fcb83d
commit 2b572f5376
2 changed files with 44 additions and 12 deletions

View File

@ -265,6 +265,9 @@ public:
timer.run();
}
// useful for testing
static size_t get_wheel_size() { return WHEEL_SIZE; }
private:
timer_impl& alloc_timer()
{
@ -306,7 +309,8 @@ private:
uint32_t timeout = cur_time + timer.duration;
size_t new_wheel_pos = timeout & WHEEL_MASK;
if (timer.is_running() and (timer.timeout & WHEEL_MASK) == new_wheel_pos) {
// If no change in timer wheel position
// If no change in timer wheel position. Just update absolute timeout
timer.timeout = timeout;
return;
}

View File

@ -25,6 +25,7 @@ int timers_test1()
uint32_t dur = 5;
{
// TEST: default ctor places unique_timer in correct state
timer_handler::unique_timer t = timers.get_unique_timer();
TESTASSERT(not t.is_running() and not t.is_expired());
TESTASSERT(t.id() == 0);
@ -103,7 +104,6 @@ int timers_test1()
timers.step_all();
TESTASSERT(t.is_expired() and t2.is_expired() and t3.is_expired());
TESTASSERT(first_id == 1);
printf("Last timer id=%d\n", last_id);
TESTASSERT(last_id == 2);
}
// TEST: timer dtor is called and removes "timer" from "timers"
@ -112,13 +112,13 @@ int timers_test1()
return SRSRAN_SUCCESS;
}
/**
* Description:
* - calling stop() early, forbids the timer from getting expired
* - calling stop() after timer has expired should be a noop
*/
int timers_test2()
{
/**
* Description:
* - calling stop() early, forbids the timer from getting expired
* - calling stop() after timer has expired should be a noop
*/
timer_handler timers;
uint32_t duration = 2;
@ -147,12 +147,12 @@ int timers_test2()
return SRSRAN_SUCCESS;
}
/**
* Description:
* - setting a new duration while the timer is already running should not stop timer, and should extend timeout
*/
int timers_test3()
{
/**
* Description:
* - setting a new duration while the timer is already running should not stop timer, and should extend timeout
*/
timer_handler timers;
uint32_t duration = 5;
@ -173,7 +173,7 @@ int timers_test3()
TESTASSERT(utimer.is_running());
}
timers.step_all();
TESTASSERT(not utimer.is_running());
TESTASSERT(not utimer.is_running() and utimer.is_expired());
return SRSRAN_SUCCESS;
}
@ -391,6 +391,33 @@ int timers_test6()
return SRSRAN_SUCCESS;
}
/**
* Test if overwriting same position of the timers handler's time wheel is safe
*/
int timers_test7()
{
timer_handler timers;
size_t wheel_size = timer_handler::get_wheel_size();
unique_timer t = timers.get_unique_timer();
t.set(2);
t.run();
timers.step_all();
TESTASSERT(not t.is_expired() and t.is_running());
// should fall in same wheel position
t.set(1 + wheel_size);
for (size_t i = 0; i < wheel_size; ++i) {
timers.step_all();
TESTASSERT(not t.is_expired() and t.is_running());
}
timers.step_all();
TESTASSERT(t.is_expired() and not t.is_running());
return SRSRAN_SUCCESS;
}
int main()
{
TESTASSERT(timers_test1() == SRSRAN_SUCCESS);
@ -399,6 +426,7 @@ int main()
TESTASSERT(timers_test4() == SRSRAN_SUCCESS);
TESTASSERT(timers_test5() == SRSRAN_SUCCESS);
TESTASSERT(timers_test6() == SRSRAN_SUCCESS);
TESTASSERT(timers_test7() == SRSRAN_SUCCESS);
printf("Success\n");
return 0;
}