From 1fe8269399c9a4604e844a3373145832705e75e5 Mon Sep 17 00:00:00 2001 From: Yasushi SHOJI Date: Thu, 1 Aug 2019 16:46:22 +0900 Subject: [PATCH] test: kernel: sched: Add a test for nested scheduler lock Add a new test for unlocking nested scheduler lock. Make sure that k_sched_unlock() isn't unconditionally a preemption point. Signed-off-by: Yasushi SHOJI --- tests/kernel/sched/schedule_api/src/main.c | 1 + .../sched/schedule_api/src/test_sched.h | 1 + .../src/test_sched_timeslice_and_lock.c | 49 +++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/tests/kernel/sched/schedule_api/src/main.c b/tests/kernel/sched/schedule_api/src/main.c index b0e37e9b37d..75eab936d26 100644 --- a/tests/kernel/sched/schedule_api/src/main.c +++ b/tests/kernel/sched/schedule_api/src/main.c @@ -65,6 +65,7 @@ void test_main(void) ztest_unit_test(test_time_slicing_disable_preemptible), ztest_unit_test(test_lock_preemptible), ztest_unit_test(test_unlock_preemptible), + ztest_unit_test(test_unlock_nested_sched_lock), ztest_unit_test(test_sched_is_preempt_thread), ztest_unit_test(test_slice_reset), ztest_unit_test(test_slice_scheduling), diff --git a/tests/kernel/sched/schedule_api/src/test_sched.h b/tests/kernel/sched/schedule_api/src/test_sched.h index b6db88a0a47..249f0deb6a1 100644 --- a/tests/kernel/sched/schedule_api/src/test_sched.h +++ b/tests/kernel/sched/schedule_api/src/test_sched.h @@ -37,6 +37,7 @@ void test_time_slicing_preemptible(void); void test_time_slicing_disable_preemptible(void); void test_lock_preemptible(void); void test_unlock_preemptible(void); +void test_unlock_nested_sched_lock(void); void test_sched_is_preempt_thread(void); void test_slice_reset(void); void test_slice_scheduling(void); diff --git a/tests/kernel/sched/schedule_api/src/test_sched_timeslice_and_lock.c b/tests/kernel/sched/schedule_api/src/test_sched_timeslice_and_lock.c index 137eb507120..401f27db7f5 100644 --- a/tests/kernel/sched/schedule_api/src/test_sched_timeslice_and_lock.c +++ b/tests/kernel/sched/schedule_api/src/test_sched_timeslice_and_lock.c @@ -365,6 +365,55 @@ void test_unlock_preemptible(void) teardown_threads(); } +/** + * @brief Validate nested k_sched_lock() and k_sched_unlock() + * + * @details In a preemptive thread, lock the scheduler twice and + * create a cooperative thread. Call k_sched_unlock() and check the + * cooperative thread haven't executed. Unlock it again to see the + * thread have executed this time. + * + * @see k_sched_lock(), k_sched_unlock() + * + * @ingroup kernel_sched_tests + */ +void test_unlock_nested_sched_lock(void) +{ + /* set current thread to a preemptible priority */ + init_prio = 0; + setup_threads(); + + /* take the scheduler lock twice */ + k_sched_lock(); + k_sched_lock(); + + /* spawn threads without wait */ + spawn_threads(0); + + /* do critical thing */ + k_busy_wait(100000); + + /* unlock once; this shouldn't let other threads to run */ + k_sched_unlock(); + + /* checkpoint: no threads get executed */ + for (int i = 0; i < THREADS_NUM; i++) { + zassert_true(tdata[i].executed == 0, NULL); + } + + /* unlock another; this let the higher thread to run */ + k_sched_unlock(); + + /* checkpoint: higher threads NOT get executed */ + zassert_true(tdata[0].executed == 1, NULL); + for (int i = 1; i < THREADS_NUM; i++) { + zassert_true(tdata[i].executed == 0, NULL); + } + + /* restore environment */ + teardown_threads(); +} + /** * @brief validate k_wakeup() in some corner scenario * @details trigger a timer and after expiration of timer