This is an automated email from the ASF dual-hosted git repository. jerzy pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
The following commit(s) were added to refs/heads/master by this push: new 955672b79 os/kernel: Add scheduler locking functionality 955672b79 is described below commit 955672b7937ea1f6d41ec009b84aa0118a4b3c71 Author: Jerzy Kasenberg <jerzy.kasenb...@codecoup.pl> AuthorDate: Tue Nov 29 13:05:03 2022 +0100 os/kernel: Add scheduler locking functionality This change add possibility to lock task scheduling temporarily. Pair of functions os_sched_suspend/os_sched_resume is added to allow task switching to be suspended while interrupts are still enabled. --- kernel/os/include/os/os_sched.h | 22 ++++++++++++++++++++++ kernel/os/src/os_sched.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/kernel/os/include/os/os_sched.h b/kernel/os/include/os/os_sched.h index 8ac73d0e8..f1c9073c6 100644 --- a/kernel/os/include/os/os_sched.h +++ b/kernel/os/include/os/os_sched.h @@ -57,6 +57,28 @@ struct os_task *os_sched_get_current_task(void); void os_sched_set_current_task(struct os_task *); struct os_task *os_sched_next_task(void); +/** + * Suspend task scheduling + * + * Function suspends the scheduler. + * Suspending the scheduler prevents a context switch but leaves interrupts enabled. + * Call to os_sched_resume() enables task scheduling again. + * Calls to os_sched_suspend() can be nested. The same number of calls must be made + * to os_sched_resume() as have previously been made to os_sched_suspend() before + * task scheduling work again. + */ +void os_sched_suspend(void); + +/** + * Resume task scheduling + * + * Resumes the scheduler after it was suspended with os_sched_suspend(). + * @returns 0 when scheduling resumed + * @returns non-0 when scheduling is still locked and more calls + * to os_sched_resume() are needed + */ +int os_sched_resume(void); + /** * Performs context switch if needed. If next_t is set, that task will be made * running. If next_t is NULL, highest priority ready to run is swapped in. This diff --git a/kernel/os/src/os_sched.c b/kernel/os/src/os_sched.c index 151079ee5..ff192d8ea 100644 --- a/kernel/os/src/os_sched.c +++ b/kernel/os/src/os_sched.c @@ -28,6 +28,7 @@ struct os_task *g_current_task; extern os_time_t g_os_time; os_time_t g_os_last_ctx_sw_time; +static uint8_t os_sched_lock_count; /** * os sched insert @@ -121,6 +122,10 @@ os_sched(struct os_task *next_t) { os_sr_t sr; + if (os_sched_lock_count) { + return; + } + OS_ENTER_CRITICAL(sr); if (!next_t) { @@ -132,6 +137,31 @@ os_sched(struct os_task *next_t) OS_EXIT_CRITICAL(sr); } +void +os_sched_suspend(void) +{ + os_sr_t sr; + OS_ENTER_CRITICAL(sr); + os_sched_lock_count++; + OS_EXIT_CRITICAL(sr); +} + +int +os_sched_resume(void) +{ + os_sr_t sr; + int ret = 0; + + OS_ENTER_CRITICAL(sr); + if (--os_sched_lock_count == 0) { + os_sched(NULL); + } + ret = os_sched_lock_count; + OS_EXIT_CRITICAL(sr); + + return ret; +} + /** * os sched sleep *