Skip to content

Commit 430c2dd

Browse files
Janosch MachowinskiJanosch Machowinski
authored andcommitted
perf: Don't wake the timer thread if not needed
In case the next timer wakeup time is not changed by an insertion of a timer, don't wake up the timer thread. Signed-off-by: Janosch Machowinski <J.Machowinski@cellumation.com>
1 parent 80cc919 commit 430c2dd

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

rclcpp/src/rclcpp/executors/events_cbg_executor/timer_manager.hpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,12 @@ class TimerQueue
339339
*/
340340
void add_timer_to_running_map(TimerData * timer_data)
341341
{
342+
bool wasEmpty = running_timers.empty();
343+
std::chrono::nanoseconds old_next_call_time(-1);
344+
if(!wasEmpty) {
345+
old_next_call_time = running_timers.begin()->first;
346+
}
347+
342348
// timer can already be in the running list, if
343349
// e.g. reset was called on a running timer
344350
if(timer_data->in_running_list) {
@@ -352,23 +358,16 @@ class TimerQueue
352358
}
353359

354360
int64_t next_call_time{};
355-
356361
rcl_ret_t ret = rcl_timer_get_next_call_time(timer_data->rcl_ref.get(), &next_call_time);
357362

358363
if (ret != RCL_RET_OK) {
359364
return;
360365
}
361366

362-
bool wasEmpty = running_timers.empty();
363-
std::chrono::nanoseconds old_next_call_time(-1);
364-
if(!wasEmpty) {
365-
old_next_call_time = running_timers.begin()->first;
366-
}
367-
368367
running_timers.emplace(next_call_time, timer_data);
369368
timer_data->in_running_list = true;
370369

371-
if(wasEmpty || old_next_call_time != running_timers.begin()->first) {
370+
if(wasEmpty || running_timers.begin()->first < old_next_call_time) {
372371
// the next wakeup is now earlier, wake up the timer thread so that it can pick up the timer
373372
wakeup_timer_thread();
374373
}
@@ -385,17 +384,18 @@ class TimerQueue
385384
}
386385

387386
int64_t time_until_call{};
387+
TimerData *timer_data(running_timers.begin()->second);
388388

389-
const rcl_timer_t * rcl_timer_ref = running_timers.begin()->second->rcl_ref.get();
389+
const rcl_timer_t * rcl_timer_ref = timer_data->rcl_ref.get();
390390
auto ret = rcl_timer_get_time_until_next_call(rcl_timer_ref, &time_until_call);
391391
if (ret == RCL_RET_TIMER_CANCELED) {
392-
running_timers.begin()->second->in_running_list = false;
392+
timer_data->in_running_list = false;
393393
running_timers.erase(running_timers.begin());
394394
continue;
395395
}
396396

397397
if (time_until_call <= 0) {
398-
auto timer_done_callback = [timer_data = running_timers.begin()->second, this] ()
398+
auto timer_done_callback = [timer_data = timer_data, this] ()
399399
{
400400
// Note, we have the guarantee, that the shared_ptr to this timer is
401401
// valid in case this callback is executed, as the executor holds a
@@ -408,14 +408,14 @@ class TimerQueue
408408
};
409409

410410
ready_timer_callbacks.push_back([ready_callback =
411-
running_timers.begin()->second->timer_ready_callback,
411+
timer_data->timer_ready_callback,
412412
done_callback = std::move(timer_done_callback)] () {
413413
ready_callback(done_callback);
414414
});
415415

416416
// remove timer from, running list, until it was executed
417417
// the scheduler will readd the timer after execution
418-
running_timers.begin()->second->in_running_list = false;
418+
timer_data->in_running_list = false;
419419
running_timers.erase(running_timers.begin());
420420

421421
continue;

0 commit comments

Comments
 (0)