From 551192705e59996100ba6a07eab90dc93e3d7e76 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 17 Sep 2019 11:29:03 +0100 Subject: [PATCH] allow for pre-reservation of timers vector and priority queue --- lib/include/srslte/common/timers.h | 15 +++ lib/test/common/timer_test.cc | 147 +++++++++++++++-------------- 2 files changed, 92 insertions(+), 70 deletions(-) diff --git a/lib/include/srslte/common/timers.h b/lib/include/srslte/common/timers.h index 55ad72863..756203c86 100644 --- a/lib/include/srslte/common/timers.h +++ b/lib/include/srslte/common/timers.h @@ -29,6 +29,7 @@ #ifndef SRSLTE_TIMERS_H #define SRSLTE_TIMERS_H +#include #include #include #include @@ -284,6 +285,16 @@ public: uint32_t timer_id; }; + explicit timers2(uint32_t capacity = 64) + { + timer_list.reserve(capacity); + // reserve a priority queue using a vector + std::vector v; + v.reserve(capacity); + std::priority_queue q(std::less(), std::move(v)); + running_timers = std::move(q); + } + void step_all() { cur_time++; @@ -325,6 +336,10 @@ public: } uint32_t get_cur_time() const { return cur_time; } + uint32_t nof_timers() const + { + return std::count_if(timer_list.begin(), timer_list.end(), [](const timer_impl& t) { return t.active; }); + } private: struct timer_run { diff --git a/lib/test/common/timer_test.cc b/lib/test/common/timer_test.cc index 961e2ab6a..4a50d1d45 100644 --- a/lib/test/common/timer_test.cc +++ b/lib/test/common/timer_test.cc @@ -37,85 +37,92 @@ int timers2_test() timers2 timers; uint32_t dur = 5; - timers2::unique_timer t = timers.get_unique_timer(); - TESTASSERT(not t.is_running() and not t.is_expired()) - TESTASSERT(t.id() == 0) - timers2::unique_timer t2 = timers.get_unique_timer(); - TESTASSERT(not t2.is_running() and not t2.is_expired()) - TESTASSERT(t2.id() == 1) + { + timers2::unique_timer t = timers.get_unique_timer(); + TESTASSERT(not t.is_running() and not t.is_expired()) + TESTASSERT(t.id() == 0) + timers2::unique_timer t2 = timers.get_unique_timer(); + TESTASSERT(not t2.is_running() and not t2.is_expired()) + TESTASSERT(t2.id() == 1) + TESTASSERT(timers.nof_timers() == 2) - // TEST: Run multiple times with the same duration - bool callback_called = false; - t.set(dur, [&callback_called](int) { callback_called = true; }); - for (uint32_t runs = 0; runs < 3; ++runs) { - callback_called = false; - TESTASSERT(not t.is_running()) - t.run(); - TESTASSERT(t.is_running() and not t.is_expired()) - for (uint32_t i = 0; i < dur; ++i) { - timers.step_all(); + // TEST: Run multiple times with the same duration + bool callback_called = false; + t.set(dur, [&callback_called](int) { callback_called = true; }); + TESTASSERT(timers.get_cur_time() == 0) + for (uint32_t runs = 0; runs < 3; ++runs) { + callback_called = false; + TESTASSERT(not t.is_running()) + t.run(); TESTASSERT(t.is_running() and not t.is_expired()) + for (uint32_t i = 0; i < dur; ++i) { + timers.step_all(); + TESTASSERT(t.is_running() and not t.is_expired()) + } + timers.step_all(); + TESTASSERT(not t.is_running() and t.is_expired()) + TESTASSERT(callback_called) } - timers.step_all(); - TESTASSERT(not t.is_running() and t.is_expired()) - TESTASSERT(callback_called) - } + TESTASSERT(timers.get_cur_time() == 3 * (1 + dur)) - // TEST: interrupt a timer. check if callback was called - callback_called = false; - t.run(); - timers.step_all(); - TESTASSERT(t.is_running()) - t.stop(); - TESTASSERT(not t.is_running()) - for (uint32_t i = 0; i < dur; ++i) { - timers.step_all(); - TESTASSERT(not t.is_running()) - } - TESTASSERT(not callback_called) - - // TEST: call timer::run() when it is already running. Check if duration gets extended. - callback_called = false; - t.run(); - timers.step_all(); - TESTASSERT(t.is_running()) - t.run(); // re-run - for (uint32_t i = 0; i < dur; ++i) { + // TEST: interrupt a timer. check if callback was called + callback_called = false; + t.run(); timers.step_all(); TESTASSERT(t.is_running()) - } - timers.step_all(); - TESTASSERT(not t.is_running()) - TESTASSERT(callback_called) - - // TEST: ordering of timers is respected - timers2::unique_timer t3 = timers.get_unique_timer(); - TESTASSERT(t3.id() == 2) - int first_id = -1, last_id = -1; - auto callback = [&first_id, &last_id](int id) { - if (first_id < 0) { - printf("First timer id=%d\n", id); - first_id = id; + t.stop(); + TESTASSERT(not t.is_running()) + for (uint32_t i = 0; i < dur; ++i) { + timers.step_all(); + TESTASSERT(not t.is_running()) } - last_id = id; - }; - t.set(4, callback); - t2.set(2, callback); - t3.set(6, callback); - t.run(); - t2.run(); - t3.run(); - for (uint32_t i = 0; i < 6; ++i) { + TESTASSERT(not callback_called) + + // TEST: call timer::run() when it is already running. Check if duration gets extended. + callback_called = false; + t.run(); timers.step_all(); - TESTASSERT(i >= 4 or t.is_running()) - TESTASSERT(i >= 2 or t2.is_running()) - TESTASSERT(t3.is_running()) + TESTASSERT(t.is_running()) + t.run(); // re-run + for (uint32_t i = 0; i < dur; ++i) { + timers.step_all(); + TESTASSERT(t.is_running()) + } + timers.step_all(); + TESTASSERT(not t.is_running()) + TESTASSERT(callback_called) + + // TEST: ordering of timers is respected + timers2::unique_timer t3 = timers.get_unique_timer(); + TESTASSERT(t3.id() == 2) + int first_id = -1, last_id = -1; + auto callback = [&first_id, &last_id](int id) { + if (first_id < 0) { + printf("First timer id=%d\n", id); + first_id = id; + } + last_id = id; + }; + t.set(4, callback); + t2.set(2, callback); + t3.set(6, callback); + t.run(); + t2.run(); + t3.run(); + for (uint32_t i = 0; i < 6; ++i) { + timers.step_all(); + TESTASSERT(i >= 4 or t.is_running()) + TESTASSERT(i >= 2 or t2.is_running()) + TESTASSERT(t3.is_running()) + } + 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) } - 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" + TESTASSERT(timers.nof_timers() == 0) printf("Success\n");