kernel: allow threads to sleep forever

Previously, passing K_FOREVER to k_sleep() would return
immediately.

Forever is a long time. Even if woken up at some point,
we still had forever to sleep, so return K_FOREVER in this
case.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2019-11-08 10:44:22 -08:00 committed by Carles Cufí
commit d2b8922fa3
2 changed files with 40 additions and 2 deletions

View file

@ -975,6 +975,11 @@ s32_t z_impl_k_sleep(int ms)
{ {
s32_t ticks; s32_t ticks;
if (ms == K_FOREVER) {
k_thread_suspend(_current);
return K_FOREVER;
}
ticks = k_ms_to_ticks_ceil32(ms); ticks = k_ms_to_ticks_ceil32(ms);
ticks = z_tick_sleep(ticks); ticks = z_tick_sleep(ticks);
return k_ticks_to_ms_floor64(ticks); return k_ticks_to_ms_floor64(ticks);
@ -1012,7 +1017,10 @@ void z_impl_k_wakeup(k_tid_t thread)
} }
if (z_abort_thread_timeout(thread) < 0) { if (z_abort_thread_timeout(thread) < 0) {
return; /* Might have just been sleeping forever */
if (thread->base.thread_state != _THREAD_SUSPENDED) {
return;
}
} }
z_mark_thread_as_not_suspended(thread); z_mark_thread_as_not_suspended(thread);

View file

@ -235,11 +235,41 @@ void test_sleep(void)
extern void test_usleep(void); extern void test_usleep(void);
static void forever_thread_entry(void *p1, void *p2, void *p3)
{
s32_t ret;
ret = k_sleep(K_FOREVER);
zassert_equal(ret, K_FOREVER, "unexpected return value");
k_sem_give(&test_thread_sem);
}
void test_sleep_forever(void)
{
test_objects_init();
test_thread_id = k_thread_create(&test_thread_data,
test_thread_stack,
THREAD_STACK,
forever_thread_entry,
0, 0, NULL, TEST_THREAD_PRIORITY,
K_USER | K_INHERIT_PERMS, K_NO_WAIT);
/* Allow forever thread to run */
k_yield();
k_wakeup(test_thread_id);
k_sem_take(&test_thread_sem, K_FOREVER);
}
/*test case main entry*/ /*test case main entry*/
void test_main(void) void test_main(void)
{ {
k_thread_access_grant(k_current_get(), &test_thread_sem);
ztest_test_suite(sleep, ztest_test_suite(sleep,
ztest_1cpu_unit_test(test_sleep), ztest_1cpu_unit_test(test_sleep),
ztest_1cpu_user_unit_test(test_usleep)); ztest_1cpu_user_unit_test(test_usleep),
ztest_1cpu_unit_test(test_sleep_forever));
ztest_run_test_suite(sleep); ztest_run_test_suite(sleep);
} }