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
  *

Reply via email to