new method in timer_handler to dispatch calls without an associated unique_timer

master
Francisco Paisana 5 years ago
parent af76778fc8
commit 5b2da779b7

@ -142,7 +142,7 @@ public:
class unique_timer class unique_timer
{ {
public: public:
unique_timer() : parent(nullptr), timer_id(std::numeric_limits<decltype(timer_id)>::max()) {} unique_timer() : timer_id(std::numeric_limits<decltype(timer_id)>::max()) {}
explicit unique_timer(timer_handler* parent_, uint32_t timer_id_) : parent(parent_), timer_id(timer_id_) {} explicit unique_timer(timer_handler* parent_, uint32_t timer_id_) : parent(parent_), timer_id(timer_id_) {}
unique_timer(const unique_timer&) = delete; unique_timer(const unique_timer&) = delete;
@ -154,7 +154,7 @@ public:
~unique_timer() ~unique_timer()
{ {
if (parent) { if (parent != nullptr) {
// does not call callback // does not call callback
impl()->clear(); impl()->clear();
} }
@ -207,7 +207,7 @@ public:
const timer_impl* impl() const { return &parent->timer_list[timer_id]; } const timer_impl* impl() const { return &parent->timer_list[timer_id]; }
timer_handler* parent; timer_handler* parent = nullptr;
uint32_t timer_id; uint32_t timer_id;
}; };
@ -256,20 +256,7 @@ public:
} }
} }
unique_timer get_unique_timer() unique_timer get_unique_timer() { return unique_timer(this, alloc_timer()); }
{
uint32_t i = 0;
for (; i < timer_list.size(); ++i) {
if (not timer_list[i].active) {
break;
}
}
if (i == timer_list.size()) {
timer_list.emplace_back(this);
}
timer_list[i].active = true;
return unique_timer(this, i);
}
uint32_t get_cur_time() const { return cur_time; } uint32_t get_cur_time() const { return cur_time; }
@ -283,6 +270,19 @@ public:
return std::count_if(timer_list.begin(), timer_list.end(), [](const timer_impl& t) { return t.is_running(); }); return std::count_if(timer_list.begin(), timer_list.end(), [](const timer_impl& t) { return t.is_running(); });
} }
template <typename F>
void defer_callback(uint32_t duration, const F& func)
{
uint32_t id = alloc_timer();
std::function<void(uint32_t)> c = [func, this, id](uint32_t tid) {
func();
// auto-deletes timer
timer_list[id].clear();
};
timer_list[id].set(duration, std::move(c));
timer_list[id].run();
}
private: private:
struct timer_run { struct timer_run {
uint32_t timer_id; uint32_t timer_id;
@ -300,6 +300,21 @@ private:
} }
}; };
uint32_t alloc_timer()
{
uint32_t i = 0;
for (; i < timer_list.size(); ++i) {
if (not timer_list[i].active) {
break;
}
}
if (i == timer_list.size()) {
timer_list.emplace_back(this);
}
timer_list[i].active = true;
return i;
}
std::vector<timer_impl> timer_list; std::vector<timer_impl> timer_list;
std::priority_queue<timer_run> running_timers; std::priority_queue<timer_run> running_timers;
uint32_t cur_time = 0; uint32_t cur_time = 0;

@ -35,7 +35,7 @@
using namespace srslte; using namespace srslte;
int timers2_test() int timers_test1()
{ {
timer_handler timers; timer_handler timers;
uint32_t dur = 5; uint32_t dur = 5;
@ -130,7 +130,7 @@ int timers2_test()
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
int timers2_test2() int timers_test2()
{ {
/** /**
* Description: * Description:
@ -165,7 +165,7 @@ int timers2_test2()
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
int timers2_test3() int timers_test3()
{ {
/** /**
* Description: * Description:
@ -196,14 +196,14 @@ int timers2_test3()
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
struct timers2_test4_context { struct timers_test4_ctxt {
std::vector<timer_handler::unique_timer> timers; std::vector<timer_handler::unique_timer> timers;
srslte::tti_sync_cv tti_sync1; srslte::tti_sync_cv tti_sync1;
srslte::tti_sync_cv tti_sync2; srslte::tti_sync_cv tti_sync2;
const uint32_t duration = 1000; const uint32_t duration = 1000;
}; };
static void timers2_test4_thread(timers2_test4_context* ctx) static void timers2_test4_thread(timers_test4_ctxt* ctx)
{ {
std::mt19937 mt19937(4); std::mt19937 mt19937(4);
std::uniform_real_distribution<float> real_dist(0.0f, 1.0f); std::uniform_real_distribution<float> real_dist(0.0f, 1.0f);
@ -230,9 +230,9 @@ static void timers2_test4_thread(timers2_test4_context* ctx)
} }
} }
int timers2_test4() int timers_test4()
{ {
timers2_test4_context* ctx = new timers2_test4_context; timers_test4_ctxt* ctx = new timers_test4_ctxt;
timer_handler timers; timer_handler timers;
uint32_t nof_timers = 32; uint32_t nof_timers = 32;
std::mt19937 mt19937(4); std::mt19937 mt19937(4);
@ -305,12 +305,75 @@ int timers2_test4()
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
/**
* Description: Delaying a callback using the timer_handler
*/
int timers_test5()
{
timer_handler timers;
TESTASSERT(timers.nof_timers() == 0);
TESTASSERT(timers.nof_running_timers() == 0);
std::vector<int> vals;
// TTI 0: Add a unique_timer of duration=5
timer_handler::unique_timer t = timers.get_unique_timer();
TESTASSERT(timers.nof_timers() == 1);
t.set(5, [&vals](uint32_t tid) { vals.push_back(1); });
t.run();
TESTASSERT(timers.nof_running_timers() == 1);
timers.step_all();
// TTI 1: Add two delayed callbacks, with duration=2 and 6
{
// ensure captures by value are ok
std::string string = "test string";
timers.defer_callback(2, [&vals, string]() {
vals.push_back(2);
if (string != "test string") {
ERROR("string was not captured correctly\n");
exit(-1);
}
});
}
timers.defer_callback(6, [&vals]() { vals.push_back(3); });
TESTASSERT(timers.nof_timers() == 3);
TESTASSERT(timers.nof_running_timers() == 3);
timers.step_all();
timers.step_all();
// TTI 3: First callback should have been triggered by now
TESTASSERT(timers.nof_running_timers() == 2);
TESTASSERT(timers.nof_timers() == 2);
TESTASSERT(vals.size() == 1);
TESTASSERT(vals[0] == 2);
timers.step_all();
timers.step_all();
// TTI 5: Unique timer should have been triggered by now
TESTASSERT(timers.nof_running_timers() == 1);
TESTASSERT(timers.nof_timers() == 2);
TESTASSERT(vals.size() == 2);
TESTASSERT(vals[1] == 1);
timers.step_all();
timers.step_all();
// TTI 7: Second callback should have been triggered by now
TESTASSERT(timers.nof_running_timers() == 0);
TESTASSERT(timers.nof_timers() == 1);
TESTASSERT(vals.size() == 3);
TESTASSERT(vals[2] == 3);
return SRSLTE_SUCCESS;
}
int main() int main()
{ {
TESTASSERT(timers2_test() == SRSLTE_SUCCESS); TESTASSERT(timers_test1() == SRSLTE_SUCCESS);
TESTASSERT(timers2_test2() == SRSLTE_SUCCESS); TESTASSERT(timers_test2() == SRSLTE_SUCCESS);
TESTASSERT(timers2_test3() == SRSLTE_SUCCESS); TESTASSERT(timers_test3() == SRSLTE_SUCCESS);
TESTASSERT(timers2_test4() == SRSLTE_SUCCESS); TESTASSERT(timers_test4() == SRSLTE_SUCCESS);
TESTASSERT(timers_test5() == SRSLTE_SUCCESS);
printf("Success\n"); printf("Success\n");
return 0; return 0;
} }

Loading…
Cancel
Save