Skip to content

Commit 213c4ab

Browse files
peter-mitsisnordicjm
authored andcommitted
[nrf fromtree] kernel: Add Z_IS_TIMEOUT_RELATIVE() macro
Introduces the Z_IS_TIMEOUT_RELATIVE() macro to help ensure that checking for relative/absolute timeouts is consistent. Using this macro also helps ensure that we get the correct behavior when using 32-bit timeouts (CONFIG_TIMEOUT_64BIT=n). Signed-off-by: Peter Mitsis <[email protected]> (cherry picked from commit 701aab9)
1 parent c332d98 commit 213c4ab

File tree

7 files changed

+34
-27
lines changed

7 files changed

+34
-27
lines changed

drivers/timer/nrf_grtc_timer.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,7 @@ uint64_t z_nrf_grtc_timer_get_ticks(k_timeout_t t)
300300

301301
grtc_ticks = t.ticks * CYC_PER_TICK;
302302
abs_ticks = Z_TICK_ABS(t.ticks);
303-
if (abs_ticks < 0) {
304-
/* relative timeout */
303+
if (Z_IS_TIMEOUT_RELATIVE(t)) {
305304
return (grtc_ticks > (int64_t)COUNTER_SPAN) ?
306305
-EINVAL : (curr_time + grtc_ticks);
307306
}

drivers/timer/nrf_rtc_timer.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,7 @@ uint64_t z_nrf_rtc_timer_get_ticks(k_timeout_t t)
208208
} while (curr_time != z_nrf_rtc_timer_read());
209209

210210
abs_ticks = Z_TICK_ABS(t.ticks);
211-
if (abs_ticks < 0) {
212-
/* relative timeout */
211+
if (Z_IS_TIMEOUT_RELATIVE(t)) {
213212
return (t.ticks > COUNTER_SPAN) ?
214213
-EINVAL : (curr_time + t.ticks);
215214
}

include/zephyr/sys_clock.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,13 @@ typedef struct {
147147
*/
148148
#define Z_TICK_ABS(t) (K_TICKS_FOREVER - 1 - (t))
149149

150+
/* Test for relative timeout */
151+
#if CONFIG_TIMEOUT_64BIT
152+
#define Z_IS_TIMEOUT_RELATIVE(timeout) (Z_TICK_ABS((timeout).ticks) < 0)
153+
#else
154+
#define Z_IS_TIMEOUT_RELATIVE(timeout) true
155+
#endif
156+
150157
/* added tick needed to account for tick in progress */
151158
#define _TICK_ALIGN 1
152159

kernel/nothread.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ int32_t z_impl_k_sleep(k_timeout_t timeout)
3636
}
3737

3838
ticks = timeout.ticks;
39-
if (Z_TICK_ABS(ticks) <= 0) {
39+
if (Z_IS_TIMEOUT_RELATIVE(timeout)) {
4040
/* ticks is delta timeout */
4141
ticks_to_wait = ticks;
4242
} else {

kernel/sched.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,27 +1064,26 @@ static inline void z_vrfy_k_yield(void)
10641064
#include <zephyr/syscalls/k_yield_mrsh.c>
10651065
#endif /* CONFIG_USERSPACE */
10661066

1067-
static int32_t z_tick_sleep(k_ticks_t ticks)
1067+
static int32_t z_tick_sleep(k_timeout_t timeout)
10681068
{
10691069
uint32_t expected_wakeup_ticks;
10701070

10711071
__ASSERT(!arch_is_in_isr(), "");
10721072

1073-
LOG_DBG("thread %p for %lu ticks", _current, (unsigned long)ticks);
1073+
LOG_DBG("thread %p for %lu ticks", _current, (unsigned long)timeout.ticks);
10741074

1075-
/* wait of 0 ms is treated as a 'yield' */
1076-
if (ticks == 0) {
1075+
/* K_NO_WAIT is treated as a 'yield' */
1076+
if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
10771077
k_yield();
10781078
return 0;
10791079
}
10801080

1081-
if (Z_TICK_ABS(ticks) <= 0) {
1082-
expected_wakeup_ticks = ticks + sys_clock_tick_get_32();
1081+
if (Z_IS_TIMEOUT_RELATIVE(timeout)) {
1082+
expected_wakeup_ticks = timeout.ticks + sys_clock_tick_get_32();
10831083
} else {
1084-
expected_wakeup_ticks = Z_TICK_ABS(ticks);
1084+
expected_wakeup_ticks = Z_TICK_ABS(timeout.ticks);
10851085
}
10861086

1087-
k_timeout_t timeout = Z_TIMEOUT_TICKS(ticks);
10881087
k_spinlock_key_t key = k_spin_lock(&_sched_spinlock);
10891088

10901089
#if defined(CONFIG_TIMESLICING) && defined(CONFIG_SWAP_NONATOMIC)
@@ -1100,7 +1099,8 @@ static int32_t z_tick_sleep(k_ticks_t ticks)
11001099
uint32_t left_ticks = expected_wakeup_ticks - sys_clock_tick_get_32();
11011100

11021101
/* To handle a negative value correctly, once type-cast it to signed 32 bit */
1103-
ticks = (k_ticks_t)(int32_t)left_ticks;
1102+
k_ticks_t ticks = (k_ticks_t)(int32_t)left_ticks;
1103+
11041104
if (ticks > 0) {
11051105
return ticks;
11061106
}
@@ -1116,9 +1116,7 @@ int32_t z_impl_k_sleep(k_timeout_t timeout)
11161116

11171117
SYS_PORT_TRACING_FUNC_ENTER(k_thread, sleep, timeout);
11181118

1119-
ticks = timeout.ticks;
1120-
1121-
ticks = z_tick_sleep(ticks);
1119+
ticks = z_tick_sleep(timeout);
11221120

11231121
int32_t ret = K_TIMEOUT_EQ(timeout, K_FOREVER) ? K_TICKS_FOREVER :
11241122
k_ticks_to_ms_ceil64(ticks);
@@ -1143,7 +1141,7 @@ int32_t z_impl_k_usleep(int32_t us)
11431141
SYS_PORT_TRACING_FUNC_ENTER(k_thread, usleep, us);
11441142

11451143
ticks = k_us_to_ticks_ceil64(us);
1146-
ticks = z_tick_sleep(ticks);
1144+
ticks = z_tick_sleep(Z_TIMEOUT_TICKS(ticks));
11471145

11481146
int32_t ret = k_ticks_to_us_ceil64(ticks);
11491147

kernel/timeout.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,12 @@ void z_add_timeout(struct _timeout *to, _timeout_func_t fn,
113113
K_SPINLOCK(&timeout_lock) {
114114
struct _timeout *t;
115115

116-
if (IS_ENABLED(CONFIG_TIMEOUT_64BIT) &&
117-
(Z_TICK_ABS(timeout.ticks) >= 0)) {
116+
if (Z_IS_TIMEOUT_RELATIVE(timeout)) {
117+
to->dticks = timeout.ticks + 1 + elapsed();
118+
} else {
118119
k_ticks_t ticks = Z_TICK_ABS(timeout.ticks) - curr_tick;
119120

120121
to->dticks = MAX(1, ticks);
121-
} else {
122-
to->dticks = timeout.ticks + 1 + elapsed();
123122
}
124123

125124
for (t = first(); t != NULL; t = next(t)) {
@@ -306,10 +305,10 @@ k_timepoint_t sys_timepoint_calc(k_timeout_t timeout)
306305
} else {
307306
k_ticks_t dt = timeout.ticks;
308307

309-
if (IS_ENABLED(CONFIG_TIMEOUT_64BIT) && Z_TICK_ABS(dt) >= 0) {
310-
timepoint.tick = Z_TICK_ABS(dt);
311-
} else {
308+
if (Z_IS_TIMEOUT_RELATIVE(timeout)) {
312309
timepoint.tick = sys_clock_tick_get() + MAX(1, dt);
310+
} else {
311+
timepoint.tick = Z_TICK_ABS(dt);
313312
}
314313
}
315314

kernel/timer.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,13 @@ void z_impl_k_timer_start(struct k_timer *timer, k_timeout_t duration,
166166
* argument the same way k_sleep() does), but historical. The
167167
* timer_api test relies on this behavior.
168168
*/
169-
if (Z_TICK_ABS(duration.ticks) < 0) {
170-
duration.ticks = MAX(duration.ticks - 1, 0);
169+
if (Z_IS_TIMEOUT_RELATIVE(duration)) {
170+
/* For the duration == K_NO_WAIT case, ensure that behaviour
171+
* is consistent for both 32-bit k_ticks_t which are unsigned
172+
* and 64-bit k_ticks_t which are signed.
173+
*/
174+
duration.ticks = MAX(1, duration.ticks);
175+
duration.ticks = duration.ticks - 1;
171176
}
172177

173178
(void)z_abort_timeout(&timer->timeout);

0 commit comments

Comments
 (0)