Skip to content

Commit d43ca21

Browse files
committed
Optimize tickless tick computation
Optimize the tick computation in the following ways: 1. Use relative time rather than absolute time 2. Replace multiplication/division pair with just multiplication or division: "* 1000000ULL / OS_TICK_FREQ" -> "* US_IN_TICK" "* OS_TICK_FREQ / 1000000" -> "/ US_IN_TICK"
1 parent e03b3b6 commit d43ca21

File tree

2 files changed

+16
-11
lines changed

2 files changed

+16
-11
lines changed

rtos/TARGET_CORTEX/SysTimer.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include "hal/lp_ticker_api.h"
2727
#include "mbed_critical.h"
28+
#include "mbed_assert.h"
2829
#if defined(TARGET_CORTEX_A)
2930
#include "rtx_core_ca.h"
3031
#else//Cortex-M
@@ -37,6 +38,9 @@ extern "C" {
3738
#endif
3839
}
3940

41+
#define US_IN_TICK (1000000 / OS_TICK_FREQ)
42+
MBED_STATIC_ASSERT(1000000 % OS_TICK_FREQ == 0, "OS_TICK_FREQ must be a divisor of 1000000 for correct tick calculations");
43+
4044
#if (defined(NO_SYSTICK))
4145
/**
4246
* Return an IRQ number that can be used in the absence of SysTick
@@ -54,17 +58,17 @@ namespace rtos {
5458
namespace internal {
5559

5660
SysTimer::SysTimer() :
57-
TimerEvent(get_lp_ticker_data()), _start_time(0), _tick(0)
61+
TimerEvent(get_lp_ticker_data()), _time_us(0), _tick(0)
5862
{
59-
_start_time = ticker_read_us(_ticker_data);
63+
_time_us = ticker_read_us(_ticker_data);
6064
_suspend_time_passed = true;
6165
_suspended = false;
6266
}
6367

6468
SysTimer::SysTimer(const ticker_data_t *data) :
65-
TimerEvent(data), _start_time(0), _tick(0)
69+
TimerEvent(data), _time_us(0), _tick(0)
6670
{
67-
_start_time = ticker_read_us(_ticker_data);
71+
_time_us = ticker_read_us(_ticker_data);
6872
}
6973

7074
void SysTimer::setup_irq()
@@ -106,16 +110,16 @@ uint32_t SysTimer::resume()
106110
_suspend_time_passed = true;
107111
remove();
108112

109-
uint64_t new_tick = (ticker_read_us(_ticker_data) - _start_time) * OS_TICK_FREQ / 1000000;
110-
if (new_tick > _tick) {
113+
uint64_t elapsed_ticks = (ticker_read_us(_ticker_data) - _time_us) / US_IN_TICK;
114+
if (elapsed_ticks > 0) {
111115
// Don't update to the current tick. Instead, update to the
112116
// previous tick and let the SysTick handler increment it
113117
// to the current value. This allows scheduling restart
114118
// successfully after the OS is resumed.
115-
new_tick--;
119+
elapsed_ticks--;
116120
}
117-
uint32_t elapsed_ticks = new_tick - _tick;
118-
_tick = new_tick;
121+
_time_us += elapsed_ticks * US_IN_TICK;
122+
_tick += elapsed_ticks;
119123

120124
core_util_critical_section_exit();
121125
return elapsed_ticks;
@@ -125,7 +129,7 @@ void SysTimer::schedule_tick(uint32_t delta)
125129
{
126130
core_util_critical_section_enter();
127131

128-
insert_absolute(_start_time + (_tick + delta) * 1000000ULL / OS_TICK_FREQ);
132+
insert_absolute(_time_us + delta * US_IN_TICK);
129133

130134
core_util_critical_section_exit();
131135
}
@@ -171,6 +175,7 @@ void SysTimer::_increment_tick()
171175
// Protected function synchronized externally
172176

173177
_tick++;
178+
_time_us += US_IN_TICK;
174179
}
175180

176181
void SysTimer::handler()

rtos/TARGET_CORTEX/SysTimer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class SysTimer: private mbed::TimerEvent, private mbed::NonCopyable<SysTimer> {
117117
virtual void handler();
118118
void _increment_tick();
119119
static void _set_irq_pending();
120-
us_timestamp_t _start_time;
120+
us_timestamp_t _time_us;
121121
uint64_t _tick;
122122
bool _suspend_time_passed;
123123
bool _suspended;

0 commit comments

Comments
 (0)