From 5710e034e709933a55499d598429251ebc1afaea Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 15 Nov 2024 15:45:21 -0800 Subject: [PATCH] kernel: Introduce _THREAD_SLEEPING state bit At the present time, Zephyr does has overlap between sleeping and suspending. Not only should sleeping and suspended be orthogonal states, but we should ensure users always employ the correct API. For example, to wake a sleeping thread, k_wakeup() should be used, and to resume a suspended thread, k_thread_resume() should be used. However, at the present time k_thread_resume() can be used on a thread that called k_sleep(K_FOREVER). Sleeping should have nothing to do with suspension. This commit introduces the new _THREAD_SLEEPING thread state along with some prep-work to facilitate the decoupling of the sleeping and suspended thread states. Signed-off-by: Peter Mitsis --- include/zephyr/kernel_structs.h | 3 +++ kernel/include/kthread.h | 14 ++++++++++++-- kernel/thread.c | 1 + .../source/COMPONENT_ZEPHYR/cyabs_rtos_zephyr.c | 1 + subsys/portability/cmsis_rtos_v2/thread.c | 1 + .../thread_apis/src/test_kthread_for_each.c | 4 ++++ 6 files changed, 22 insertions(+), 2 deletions(-) diff --git a/include/zephyr/kernel_structs.h b/include/zephyr/kernel_structs.h index 3c1df990a22..e28db759bd6 100644 --- a/include/zephyr/kernel_structs.h +++ b/include/zephyr/kernel_structs.h @@ -54,6 +54,9 @@ extern "C" { /* Thread is waiting on an object */ #define _THREAD_PENDING (BIT(1)) +/* Thread is sleeping */ +#define _THREAD_SLEEPING (BIT(2)) + /* Thread has terminated */ #define _THREAD_DEAD (BIT(3)) diff --git a/kernel/include/kthread.h b/kernel/include/kthread.h index 39bea42c912..95b53521329 100644 --- a/kernel/include/kthread.h +++ b/kernel/include/kthread.h @@ -15,6 +15,7 @@ #define Z_STATE_STR_DUMMY "dummy" #define Z_STATE_STR_PENDING "pending" +#define Z_STATE_STR_SLEEPING "sleeping" #define Z_STATE_STR_DEAD "dead" #define Z_STATE_STR_SUSPENDED "suspended" #define Z_STATE_STR_ABORTING "aborting" @@ -96,9 +97,8 @@ static inline bool z_is_thread_prevented_from_running(struct k_thread *thread) { uint8_t state = thread->base.thread_state; - return (state & (_THREAD_PENDING | _THREAD_DEAD | + return (state & (_THREAD_PENDING | _THREAD_SLEEPING | _THREAD_DEAD | _THREAD_DUMMY | _THREAD_SUSPENDED)) != 0U; - } static inline bool z_is_thread_timeout_active(struct k_thread *thread) @@ -146,6 +146,16 @@ static inline void z_mark_thread_as_not_pending(struct k_thread *thread) thread->base.thread_state &= ~_THREAD_PENDING; } +static inline void z_mark_thread_as_sleeping(struct k_thread *thread) +{ + thread->base.thread_state |= _THREAD_SLEEPING; +} + +static inline void z_mark_thread_as_not_sleeping(struct k_thread *thread) +{ + thread->base.thread_state &= ~_THREAD_SLEEPING; +} + /* * This function tags the current thread as essential to system operation. * Exceptions raised by this thread will be treated as a fatal system error. diff --git a/kernel/thread.c b/kernel/thread.c index a0761645708..2e20d48245e 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -236,6 +236,7 @@ const char *k_thread_state_str(k_tid_t thread_id, char *buf, size_t buf_size) } state_string[] = { SS_ENT(DUMMY), SS_ENT(PENDING), + SS_ENT(SLEEPING), SS_ENT(DEAD), SS_ENT(SUSPENDED), SS_ENT(ABORTING), diff --git a/modules/hal_infineon/abstraction-rtos/source/COMPONENT_ZEPHYR/cyabs_rtos_zephyr.c b/modules/hal_infineon/abstraction-rtos/source/COMPONENT_ZEPHYR/cyabs_rtos_zephyr.c index c9df61b2f73..ae06b13892c 100644 --- a/modules/hal_infineon/abstraction-rtos/source/COMPONENT_ZEPHYR/cyabs_rtos_zephyr.c +++ b/modules/hal_infineon/abstraction-rtos/source/COMPONENT_ZEPHYR/cyabs_rtos_zephyr.c @@ -232,6 +232,7 @@ cy_rslt_t cy_rtos_get_thread_state(cy_thread_t *thread, cy_thread_state_t *state break; case _THREAD_SUSPENDED: + case _THREAD_SLEEPING: case _THREAD_PENDING: *state = CY_THREAD_STATE_BLOCKED; break; diff --git a/subsys/portability/cmsis_rtos_v2/thread.c b/subsys/portability/cmsis_rtos_v2/thread.c index 0a757344313..9cbc702b5fc 100644 --- a/subsys/portability/cmsis_rtos_v2/thread.c +++ b/subsys/portability/cmsis_rtos_v2/thread.c @@ -312,6 +312,7 @@ osThreadState_t osThreadGetState(osThreadId_t thread_id) state = osThreadTerminated; break; case _THREAD_SUSPENDED: + case _THREAD_SLEEPING: case _THREAD_PENDING: state = osThreadBlocked; break; diff --git a/tests/kernel/threads/thread_apis/src/test_kthread_for_each.c b/tests/kernel/threads/thread_apis/src/test_kthread_for_each.c index 71f84e7b33f..17a495523e1 100644 --- a/tests/kernel/threads/thread_apis/src/test_kthread_for_each.c +++ b/tests/kernel/threads/thread_apis/src/test_kthread_for_each.c @@ -249,6 +249,10 @@ ZTEST(threads_lifecycle_1cpu, test_k_thread_state_str) str = k_thread_state_str(tid, state_str, sizeof(state_str)); zassert_str_equal(str, "dead"); + tid->base.thread_state = _THREAD_SLEEPING; + str = k_thread_state_str(tid, state_str, sizeof(state_str)); + zassert_str_equal(str, "sleeping"); + tid->base.thread_state = _THREAD_SUSPENDED; str = k_thread_state_str(tid, state_str, sizeof(state_str)); zassert_str_equal(str, "suspended");