This is an automated email from the ASF dual-hosted git repository.

jerpelea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 02bfd290ac7 sched/sleep: add support for scheduling sleep
02bfd290ac7 is described below

commit 02bfd290ac79dca3483310cbf189502d87108f11
Author: chao an <[email protected]>
AuthorDate: Wed Oct 15 19:27:47 2025 +0800

    sched/sleep: add support for scheduling sleep
    
    Nuttx currently has 2 types of sleep interfaces:
    
    1. Signal-scheduled sleep: nxsig_sleep() / nxsig_usleep() / 
nxsig_nanosleep()
    Weaknesses:
      a. Signal-dependent: The signal-scheduled sleep method is bound to the 
signal framework, while some driver sleep operations do not depend on signals.
      b. Timespec conversion: Signal-scheduled sleep involves timespec 
conversion, which has a significant impact on performance.
    2. Busy sleep: up_mdelay() / up_udelay()
    Weaknesses:
      a. Does not actively trigger scheduling, occupy the CPU loading.
    
    3. New interfaces: Scheduled sleep: nxsched_sleep() / nxsched_usleep() / 
nxsched_msleep() / nxsched_ticksleep()
    Strengths:
      a. Does not depend on the signal framework.
      b. Tick-based, without additional computational overhead.
    
    Currently, the Nuttx driver framework extensively uses nxsig_* interfaces. 
However, the driver does not need to rely on signals or timespec conversion.
    Therefore, a new set of APIs is added to reduce dependencies on other 
modules.
    
    (This PR also aims to make signals optional, further reducing the code size 
of Nuttx.)
    
    Signed-off-by: chao an <[email protected]>
---
 include/nuttx/sched.h      |  76 ++++++++++++++++
 sched/sched/CMakeLists.txt |   3 +-
 sched/sched/Make.defs      |   2 +-
 sched/sched/sched_sleep.c  | 213 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 292 insertions(+), 2 deletions(-)

diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h
index 7bf37127e4f..977e294730f 100644
--- a/include/nuttx/sched.h
+++ b/include/nuttx/sched.h
@@ -1714,6 +1714,82 @@ int nxsched_smp_call_async(cpu_set_t cpuset,
                            FAR struct smp_call_data_s *data);
 #endif
 
+/****************************************************************************
+ * Name: nxsched_ticksleep
+ *
+ * Description:
+ *   The nxsched_ticksleep() function will cause the calling thread to be
+ *   suspended from execution for the specified number of system ticks.
+ *
+ *   It can only be resumed through scheduler operations.
+ *
+ * Input Parameters:
+ *   ticks - The number of system ticks to sleep.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void nxsched_ticksleep(unsigned int ticks);
+
+/****************************************************************************
+ * Name: nxsched_usleep
+ *
+ * Description:
+ *   The nxsched_usleep() function will cause the calling thread to be
+ *   suspended from execution for the specified number of microseconds.
+ *
+ *   It can only be resumed through scheduler.
+ *
+ * Input Parameters:
+ *   usec - The number of microseconds to sleep.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void nxsched_usleep(useconds_t usec);
+
+/****************************************************************************
+ * Name: nxsched_msleep
+ *
+ * Description:
+ *   The nxsched_msleep() function will cause the calling thread to be
+ *   suspended from execution for the specified number of milliseconds.
+ *
+ *   It can only be resumed through scheduler.
+ *
+ * Input Parameters:
+ *   msec - The number of milliseconds to sleep.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void nxsched_msleep(unsigned int msec);
+
+/****************************************************************************
+ * Name: nxsched_sleep
+ *
+ * Description:
+ *   The nxsched_sleep() function will cause the calling thread to be
+ *   suspended from execution for the specified number of seconds.
+ *
+ *   It can only be resumed through scheduler.
+ *
+ * Input Parameters:
+ *   sec - The number of seconds to sleep.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void nxsched_sleep(unsigned int sec);
+
 #undef EXTERN
 #if defined(__cplusplus)
 }
diff --git a/sched/sched/CMakeLists.txt b/sched/sched/CMakeLists.txt
index 1edfe87fc61..782234f846d 100644
--- a/sched/sched/CMakeLists.txt
+++ b/sched/sched/CMakeLists.txt
@@ -47,7 +47,8 @@ set(SRCS
     sched_get_tls.c
     sched_sysinfo.c
     sched_get_stateinfo.c
-    sched_switchcontext.c)
+    sched_switchcontext.c
+    sched_sleep.c)
 
 if(DEFINED CONFIG_STACKCHECK_MARGIN)
   if(NOT CONFIG_STACKCHECK_MARGIN EQUAL -1)
diff --git a/sched/sched/Make.defs b/sched/sched/Make.defs
index 7cc19db557b..71a7bc2ce6b 100644
--- a/sched/sched/Make.defs
+++ b/sched/sched/Make.defs
@@ -30,7 +30,7 @@ CSRCS += sched_yield.c sched_rrgetinterval.c sched_foreach.c
 CSRCS += sched_lock.c sched_unlock.c sched_lockcount.c
 CSRCS += sched_idletask.c sched_self.c sched_get_stackinfo.c sched_get_tls.c
 CSRCS += sched_sysinfo.c sched_get_stateinfo.c sched_getcpu.c
-CSRCS += sched_switchcontext.c
+CSRCS += sched_switchcontext.c sched_sleep.c
 
 ifneq ($(CONFIG_STACKCHECK_MARGIN),)
   ifneq ($(CONFIG_STACKCHECK_MARGIN),-1)
diff --git a/sched/sched/sched_sleep.c b/sched/sched/sched_sleep.c
new file mode 100644
index 00000000000..6c01f15483d
--- /dev/null
+++ b/sched/sched/sched_sleep.c
@@ -0,0 +1,213 @@
+/****************************************************************************
+ * sched/sched/sched_sleep.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/clock.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxsched_timeout
+ *
+ * Description:
+ *   A timeout elapsed while waiting for timeout.
+ *
+ * Assumptions:
+ *   This function executes in the context of the timer interrupt handler.
+ *   Local interrupts are assumed to be disabled on entry.
+ *
+ * Input Parameters:
+ *   arg - Parameter to pass to wdentry.
+ *
+ ****************************************************************************/
+
+static void nxsched_timeout(wdparm_t arg)
+{
+  FAR struct tcb_s *wtcb;
+  irqstate_t flags;
+
+  /* Get waiting tcb from parameter */
+
+  wtcb = (FAR struct tcb_s *)(uintptr_t)arg;
+
+  /* We must be in a critical section in order to call up_switch_context()
+   * below.
+   */
+
+  flags = enter_critical_section();
+
+  /* There may be a race condition -- make sure the task is
+   * still waiting for a signal
+   */
+
+  if (wtcb->task_state == TSTATE_WAIT_SIG)
+    {
+      FAR struct tcb_s *rtcb = this_task();
+
+      /* Remove the task from waiting list */
+
+      dq_rem((FAR dq_entry_t *)wtcb, list_waitingforsignal());
+
+      /* Add the task to ready-to-run task list, and
+       * perform the context switch if one is needed
+       */
+
+      if (nxsched_add_readytorun(wtcb))
+        {
+          up_switch_context(this_task(), rtcb);
+        }
+    }
+
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: nxsched_ticksleep
+ *
+ * Description:
+ *   The nxsched_ticksleep() function will cause the calling thread to be
+ *   suspended from execution for the specified number of system ticks.
+ *
+ *   It can only be resumed through scheduler operations.
+ *
+ * Input Parameters:
+ *   ticks - The number of system ticks to sleep.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void nxsched_ticksleep(unsigned int ticks)
+{
+  FAR struct tcb_s *rtcb;
+  irqstate_t flags;
+
+  if (ticks == 0)
+    {
+      sched_yield();
+      return;
+    }
+
+  flags = enter_critical_section();
+
+  rtcb = this_task();
+
+  wd_start(&rtcb->waitdog, ticks, nxsched_timeout, (uintptr_t)rtcb);
+
+  /* Remove the tcb task from the ready-to-run list. */
+
+  nxsched_remove_self(rtcb);
+
+  /* Add the task to the specified blocked task list */
+
+  rtcb->task_state = TSTATE_WAIT_SIG;
+  dq_addlast((FAR dq_entry_t *)rtcb, &g_waitingforsignal);
+
+  /* Now, perform the context switch if one is needed */
+
+  up_switch_context(this_task(), rtcb);
+
+  wd_cancel(&rtcb->waitdog);
+
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxsched_usleep
+ *
+ * Description:
+ *   The nxsched_usleep() function will cause the calling thread to be
+ *   suspended from execution for the specified number of microseconds.
+ *
+ *   It can only be resumed through scheduler.
+ *
+ * Input Parameters:
+ *   usec - The number of microseconds to sleep.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void nxsched_usleep(useconds_t usec)
+{
+  nxsched_ticksleep(USEC2TICK(usec));
+}
+
+/****************************************************************************
+ * Name: nxsched_msleep
+ *
+ * Description:
+ *   The nxsched_msleep() function will cause the calling thread to be
+ *   suspended from execution for the specified number of milliseconds.
+ *
+ *   It can only be resumed through scheduler.
+ *
+ * Input Parameters:
+ *   msec - The number of milliseconds to sleep.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void nxsched_msleep(unsigned int msec)
+{
+  nxsched_ticksleep(MSEC2TICK(msec));
+}
+
+/****************************************************************************
+ * Name: nxsched_sleep
+ *
+ * Description:
+ *   The nxsched_sleep() function will cause the calling thread to be
+ *   suspended from execution for the specified number of seconds.
+ *
+ *   It can only be resumed through scheduler.
+ *
+ * Input Parameters:
+ *   sec - The number of seconds to sleep.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void nxsched_sleep(unsigned int sec)
+{
+  nxsched_ticksleep(SEC2TICK(sec));
+}

Reply via email to