From 25a4fd1107cf78fd3e0345ff7d291b195a31de3d Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Sat, 5 Feb 2022 17:10:57 +0100 Subject: [PATCH] Allow adding timers from timer callbacks. --- core/timermanager.cpp | 24 ++++++++++++++++++------ core/timermanager.h | 9 +++++---- cpu/ppc/ppcexec.cpp | 8 +++++--- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/core/timermanager.cpp b/core/timermanager.cpp index d6f6187..1ae438e 100644 --- a/core/timermanager.cpp +++ b/core/timermanager.cpp @@ -48,7 +48,9 @@ uint32_t TimerManager::add_oneshot_timer(uint64_t timeout, timer_cb cb) this->timer_queue.push(timer_desc); // notify listeners about changes in the timer queue - this->notify_timer_changes(); + if (!this->cb_active) { + this->notify_timer_changes(); + } return ti->id; } @@ -72,7 +74,9 @@ uint32_t TimerManager::add_cyclic_timer(uint64_t interval, timer_cb cb) this->timer_queue.push(timer_desc); // notify listeners about changes in the timer queue - this->notify_timer_changes(); + if (!this->cb_active) { + this->notify_timer_changes(); + } return ti->id; } @@ -85,7 +89,9 @@ void TimerManager::cancel_timer(uint32_t id) } else { this->timer_queue.remove_by_id(id); } - this->notify_timer_changes(); + if (!this->cb_active) { + this->notify_timer_changes(); + } } uint64_t TimerManager::process_timers(uint64_t time_now) @@ -100,8 +106,7 @@ uint64_t TimerManager::process_timers(uint64_t time_now) cur_timer = this->timer_queue.top().get(); while (cur_timer->timeout_ns <= time_now || cur_timer->timeout_ns <= (time_now + MIN_TIMEOUT_NS)) { - // invoke timer callback - cur_timer->cb(); + timer_cb cb = cur_timer->cb; // re-arm cyclic timers if (cur_timer->interval_ns) { @@ -114,6 +119,13 @@ uint64_t TimerManager::process_timers(uint64_t time_now) this->timer_queue.pop(); } + this->cb_active = true; + + // invoke timer callback + cb(); + + this->cb_active = false; + // process next timer if (this->timer_queue.empty()) { return 0ULL; @@ -124,4 +136,4 @@ uint64_t TimerManager::process_timers(uint64_t time_now) // return time slice in nanoseconds until next timer's expiry return cur_timer->timeout_ns - time_now; -} \ No newline at end of file +} diff --git a/core/timermanager.h b/core/timermanager.h index 9b56660..ec02738 100644 --- a/core/timermanager.h +++ b/core/timermanager.h @@ -82,7 +82,7 @@ public: return timer_manager; }; - // callback ´for retrieving current time + // callback for retrieving current time void set_time_now_cb(const function &cb) { this->get_time_now = cb; }; @@ -103,13 +103,14 @@ private: static TimerManager* timer_manager; TimerManager(){}; // private constructor to implement a singleton - uint32_t id = 0; - // timer queue my_priority_queue, vector>, MyGtComparator> timer_queue; function get_time_now; function notify_timer_changes; + + uint32_t id = 0; + bool cb_active = false; // true if a timer callback is executing }; -#endif // TIMER_MANAGER_H \ No newline at end of file +#endif // TIMER_MANAGER_H diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index 258af30..0fde991 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -319,7 +319,11 @@ uint64_t process_events() void force_cycle_counter_reload() { // tell the interpreter loop to reload cycle counter - bb_kind = BB_end_kind::BB_TIMER; + if (bb_kind == BB_end_kind::BB_NONE || bb_kind == BB_end_kind::BB_TIMER) { + bb_kind = BB_end_kind::BB_TIMER; + } else { + ABORT_F("PPCEXEC: attempt to override basic block type %d", bb_kind); + } } /** Execute PPC code as long as power is on. */ @@ -412,7 +416,6 @@ static void ppc_exec_inner() max_cycles = process_events(); } - //if (eb_last) { if (bb_kind != BB_end_kind::BB_NONE) { // execution block ended ? if (!power_on) break; @@ -611,7 +614,6 @@ static void ppc_exec_until_inner(const uint32_t goal_addr) max_cycles = process_events(); } - //if (eb_last) { if (bb_kind != BB_end_kind::BB_NONE) { // execution block ended ? // reload cycle counter if requested if (bb_kind == BB_end_kind::BB_TIMER) {