Skip to content

Commit 6d35969

Browse files
nordic-krchkartben
authored andcommitted
kernel: sched: Optimize sleeping function
Accessing system timer registers can be costly and it shall be avoided if possible. When thread is waken up in z_tick_sleep it may be because timeout expired or because thread was waken up before sleeping period passed. Add function to detect if timeout is aborted (before it was expired). Use it in the sleep function and avoid reading system ticks if timeout was not aborted. Signed-off-by: Krzysztof Chruściński <[email protected]>
1 parent 3c2d2a6 commit 6d35969

File tree

3 files changed

+22
-0
lines changed

3 files changed

+22
-0
lines changed

kernel/include/timeout_q.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ extern "C" {
2222

2323
#ifdef CONFIG_SYS_CLOCK_EXISTS
2424

25+
/* Value written to dticks when timeout is aborted. */
26+
#define TIMEOUT_DTICKS_ABORTED (IS_ENABLED(CONFIG_TIMEOUT_64BIT) ? INT64_MIN : INT32_MIN)
27+
2528
static inline void z_init_timeout(struct _timeout *to)
2629
{
2730
sys_dnode_init(&to->node);
@@ -37,6 +40,12 @@ static inline bool z_is_inactive_timeout(const struct _timeout *to)
3740
return !sys_dnode_is_linked(&to->node);
3841
}
3942

43+
static inline bool z_is_aborted_timeout(const struct _timeout *to)
44+
{
45+
/* When timeout is aborted then dticks is set to special value. */
46+
return to->dticks == TIMEOUT_DTICKS_ABORTED;
47+
}
48+
4049
static inline void z_init_thread_timeout(struct _thread_base *thread_base)
4150
{
4251
z_init_timeout(&thread_base->timeout);
@@ -54,6 +63,12 @@ static inline void z_abort_thread_timeout(struct k_thread *thread)
5463
z_abort_timeout(&thread->base.timeout);
5564
}
5665

66+
static inline bool z_is_aborted_thread_timeout(struct k_thread *thread)
67+
{
68+
69+
return z_is_aborted_timeout(&thread->base.timeout);
70+
}
71+
5772
int32_t z_get_next_timeout_expiry(void);
5873

5974
k_ticks_t z_timeout_remaining(const struct _timeout *timeout);
@@ -63,7 +78,9 @@ k_ticks_t z_timeout_remaining(const struct _timeout *timeout);
6378
/* Stubs when !CONFIG_SYS_CLOCK_EXISTS */
6479
#define z_init_thread_timeout(thread_base) do {} while (false)
6580
#define z_abort_thread_timeout(to) do {} while (false)
81+
#define z_is_aborted_thread_timeout(to) false
6682
#define z_is_inactive_timeout(to) 1
83+
#define z_is_aborted_timeout(to) false
6784
#define z_get_next_timeout_expiry() ((int32_t) K_TICKS_FOREVER)
6885
#define z_set_timeout_expiry(ticks, is_idle) do {} while (false)
6986

kernel/sched.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,10 @@ static int32_t z_tick_sleep(k_timeout_t timeout)
11081108

11091109
(void)z_swap(&_sched_spinlock, key);
11101110

1111+
if (!z_is_aborted_thread_timeout(_current)) {
1112+
return 0;
1113+
}
1114+
11111115
/* We require a 32 bit unsigned subtraction to care a wraparound */
11121116
uint32_t left_ticks = expected_wakeup_ticks - sys_clock_tick_get_32();
11131117

kernel/timeout.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ int z_abort_timeout(struct _timeout *to)
162162
bool is_first = (to == first());
163163

164164
remove_timeout(to);
165+
to->dticks = TIMEOUT_DTICKS_ABORTED;
165166
ret = 0;
166167
if (is_first) {
167168
sys_clock_set_timeout(next_timeout(elapsed()), false);

0 commit comments

Comments
 (0)