aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJere Leppänen <jere.leppanen@nokia.com>2023-03-13 19:05:25 +0200
committerMatias Elo <matias.elo@nokia.com>2024-02-01 16:35:10 +0200
commit90dd758b73034ac12caf29e7ddab4ad6d3cbbbaa (patch)
tree4622f12addff0e599c30956d4851e6767d79bc0f
parentf74bd07adc50885b54036496b2f9993ebffb5bd1 (diff)
linux-gen: timer: return time to the next timeout from timer_run()
In timer_run(), return the time in nsec to the next timeout. If timer_run() expires a timer, return zero. Signed-off-by: Jere Leppänen <jere.leppanen@nokia.com> Reviewed-by: Petri Savolainen <petri.savolainen@nokia.com>
-rw-r--r--platform/linux-generic/include/odp_timer_internal.h8
-rw-r--r--platform/linux-generic/odp_timer.c30
2 files changed, 25 insertions, 13 deletions
diff --git a/platform/linux-generic/include/odp_timer_internal.h b/platform/linux-generic/include/odp_timer_internal.h
index 01ee4a0f3..9c9852de9 100644
--- a/platform/linux-generic/include/odp_timer_internal.h
+++ b/platform/linux-generic/include/odp_timer_internal.h
@@ -48,13 +48,15 @@ ODP_STATIC_ASSERT(sizeof(odp_timeout_hdr_t) <= ODP_CACHE_LINE_SIZE,
/* A larger decrement value should be used after receiving events compared to
* an 'empty' call. */
-void _odp_timer_run_inline(int dec);
+uint64_t _odp_timer_run_inline(int dec);
/* Static inline wrapper to minimize modification of schedulers. */
-static inline void timer_run(int dec)
+static inline uint64_t timer_run(int dec)
{
if (odp_global_rw->inline_timers)
- _odp_timer_run_inline(dec);
+ return _odp_timer_run_inline(dec);
+
+ return UINT64_MAX;
}
#endif
diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c
index daf187390..0b582e18b 100644
--- a/platform/linux-generic/odp_timer.c
+++ b/platform/linux-generic/odp_timer.c
@@ -761,11 +761,12 @@ static inline void timer_expire(timer_pool_t *tp, uint32_t idx, uint64_t tick)
}
}
-static inline void timer_pool_scan(timer_pool_t *tp, uint64_t tick)
+static inline uint64_t timer_pool_scan(timer_pool_t *tp, uint64_t tick)
{
tick_buf_t *array = &tp->tick_buf[0];
uint32_t high_wm = odp_atomic_load_acq_u32(&tp->high_wm);
uint32_t i;
+ uint64_t min = UINT64_MAX;
_ODP_ASSERT(high_wm <= tp->param.num_timers);
for (i = 0; i < high_wm; i++) {
@@ -780,18 +781,23 @@ static inline void timer_pool_scan(timer_pool_t *tp, uint64_t tick)
if (odp_unlikely(exp_tck <= tick)) {
/* Attempt to expire timer */
timer_expire(tp, i, tick);
+ min = 0;
+ } else {
+ min = _ODP_MIN(min, exp_tck - tick);
}
}
+
+ return min;
}
/******************************************************************************
* Inline timer processing
*****************************************************************************/
-static inline void timer_pool_scan_inline(int num, odp_time_t now)
+static inline uint64_t timer_pool_scan_inline(int num, odp_time_t now)
{
timer_pool_t *tp;
- uint64_t new_tick, old_tick, nsec;
+ uint64_t new_tick, old_tick, ticks_to_next_expire, nsec, min = UINT64_MAX;
int64_t diff;
int i;
@@ -832,26 +838,29 @@ static inline void timer_pool_scan_inline(int num, odp_time_t now)
odp_atomic_store_u32(&tp->notify_overrun, 2);
}
}
- timer_pool_scan(tp, nsec);
+ ticks_to_next_expire = timer_pool_scan(tp, nsec);
+ min = _ODP_MIN(min, ticks_to_next_expire);
}
}
+
+ return min;
}
-void _odp_timer_run_inline(int dec)
+uint64_t _odp_timer_run_inline(int dec)
{
odp_time_t now;
int num = timer_global->highest_tp_idx + 1;
int poll_interval = timer_global->poll_interval;
if (num == 0)
- return;
+ return UINT64_MAX;
/* Rate limit how often this thread checks the timer pools. */
if (poll_interval > 1) {
timer_local.run_cnt -= dec;
if (timer_local.run_cnt > 0)
- return;
+ return UINT64_MAX;
timer_local.run_cnt = poll_interval;
}
@@ -862,7 +871,7 @@ void _odp_timer_run_inline(int dec)
if (odp_time_cmp(period,
timer_global->poll_interval_time) < 0)
- return;
+ return UINT64_MAX;
timer_local.last_run = now;
}
@@ -870,13 +879,14 @@ void _odp_timer_run_inline(int dec)
if (CONFIG_TIMER_PROFILE_INLINE) {
odp_time_t t1 = odp_time_local_strict();
- timer_pool_scan_inline(num, now);
+ uint64_t ret = timer_pool_scan_inline(num, now);
odp_time_t t2 = odp_time_local_strict();
timer_local.prof_nsec += odp_time_diff_ns(t2, t1);
timer_local.prof_rounds++;
+ return ret;
} else {
- timer_pool_scan_inline(num, now);
+ return timer_pool_scan_inline(num, now);
}
}