mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-06-08 00:29:42 +00:00
Allow adding timers from timer callbacks.
This commit is contained in:
parent
5c177cc50f
commit
25a4fd1107
|
@ -48,7 +48,9 @@ uint32_t TimerManager::add_oneshot_timer(uint64_t timeout, timer_cb cb)
|
||||||
this->timer_queue.push(timer_desc);
|
this->timer_queue.push(timer_desc);
|
||||||
|
|
||||||
// notify listeners about changes in the timer queue
|
// notify listeners about changes in the timer queue
|
||||||
this->notify_timer_changes();
|
if (!this->cb_active) {
|
||||||
|
this->notify_timer_changes();
|
||||||
|
}
|
||||||
|
|
||||||
return ti->id;
|
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);
|
this->timer_queue.push(timer_desc);
|
||||||
|
|
||||||
// notify listeners about changes in the timer queue
|
// notify listeners about changes in the timer queue
|
||||||
this->notify_timer_changes();
|
if (!this->cb_active) {
|
||||||
|
this->notify_timer_changes();
|
||||||
|
}
|
||||||
|
|
||||||
return ti->id;
|
return ti->id;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +89,9 @@ void TimerManager::cancel_timer(uint32_t id)
|
||||||
} else {
|
} else {
|
||||||
this->timer_queue.remove_by_id(id);
|
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)
|
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();
|
cur_timer = this->timer_queue.top().get();
|
||||||
while (cur_timer->timeout_ns <= time_now ||
|
while (cur_timer->timeout_ns <= time_now ||
|
||||||
cur_timer->timeout_ns <= (time_now + MIN_TIMEOUT_NS)) {
|
cur_timer->timeout_ns <= (time_now + MIN_TIMEOUT_NS)) {
|
||||||
// invoke timer callback
|
timer_cb cb = cur_timer->cb;
|
||||||
cur_timer->cb();
|
|
||||||
|
|
||||||
// re-arm cyclic timers
|
// re-arm cyclic timers
|
||||||
if (cur_timer->interval_ns) {
|
if (cur_timer->interval_ns) {
|
||||||
|
@ -114,6 +119,13 @@ uint64_t TimerManager::process_timers(uint64_t time_now)
|
||||||
this->timer_queue.pop();
|
this->timer_queue.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->cb_active = true;
|
||||||
|
|
||||||
|
// invoke timer callback
|
||||||
|
cb();
|
||||||
|
|
||||||
|
this->cb_active = false;
|
||||||
|
|
||||||
// process next timer
|
// process next timer
|
||||||
if (this->timer_queue.empty()) {
|
if (this->timer_queue.empty()) {
|
||||||
return 0ULL;
|
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 time slice in nanoseconds until next timer's expiry
|
||||||
return cur_timer->timeout_ns - time_now;
|
return cur_timer->timeout_ns - time_now;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ public:
|
||||||
return timer_manager;
|
return timer_manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
// callback ´for retrieving current time
|
// callback for retrieving current time
|
||||||
void set_time_now_cb(const function<uint64_t()> &cb) {
|
void set_time_now_cb(const function<uint64_t()> &cb) {
|
||||||
this->get_time_now = cb;
|
this->get_time_now = cb;
|
||||||
};
|
};
|
||||||
|
@ -103,13 +103,14 @@ private:
|
||||||
static TimerManager* timer_manager;
|
static TimerManager* timer_manager;
|
||||||
TimerManager(){}; // private constructor to implement a singleton
|
TimerManager(){}; // private constructor to implement a singleton
|
||||||
|
|
||||||
uint32_t id = 0;
|
|
||||||
|
|
||||||
// timer queue
|
// timer queue
|
||||||
my_priority_queue<shared_ptr<TimerInfo>, vector<shared_ptr<TimerInfo>>, MyGtComparator> timer_queue;
|
my_priority_queue<shared_ptr<TimerInfo>, vector<shared_ptr<TimerInfo>>, MyGtComparator> timer_queue;
|
||||||
|
|
||||||
function<uint64_t()> get_time_now;
|
function<uint64_t()> get_time_now;
|
||||||
function<void()> notify_timer_changes;
|
function<void()> notify_timer_changes;
|
||||||
|
|
||||||
|
uint32_t id = 0;
|
||||||
|
bool cb_active = false; // true if a timer callback is executing
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TIMER_MANAGER_H
|
#endif // TIMER_MANAGER_H
|
||||||
|
|
|
@ -319,7 +319,11 @@ uint64_t process_events()
|
||||||
void force_cycle_counter_reload()
|
void force_cycle_counter_reload()
|
||||||
{
|
{
|
||||||
// tell the interpreter loop to reload cycle counter
|
// 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. */
|
/** Execute PPC code as long as power is on. */
|
||||||
|
@ -412,7 +416,6 @@ static void ppc_exec_inner()
|
||||||
max_cycles = process_events();
|
max_cycles = process_events();
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (eb_last) {
|
|
||||||
if (bb_kind != BB_end_kind::BB_NONE) { // execution block ended ?
|
if (bb_kind != BB_end_kind::BB_NONE) { // execution block ended ?
|
||||||
if (!power_on)
|
if (!power_on)
|
||||||
break;
|
break;
|
||||||
|
@ -611,7 +614,6 @@ static void ppc_exec_until_inner(const uint32_t goal_addr)
|
||||||
max_cycles = process_events();
|
max_cycles = process_events();
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (eb_last) {
|
|
||||||
if (bb_kind != BB_end_kind::BB_NONE) { // execution block ended ?
|
if (bb_kind != BB_end_kind::BB_NONE) { // execution block ended ?
|
||||||
// reload cycle counter if requested
|
// reload cycle counter if requested
|
||||||
if (bb_kind == BB_end_kind::BB_TIMER) {
|
if (bb_kind == BB_end_kind::BB_TIMER) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user