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

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

commit 8514e9978f6bd5f1a4fc3a0c754ffdbfce620a6f
Author: wangchengdong <[email protected]>
AuthorDate: Thu Feb 26 10:09:16 2026 +0800

    sched/signal: move nxsig_clockwait implementation to a separate file
    
    Move the implementation of nxsig_clockwait() into a separate file
    to decouple it from nxsig_timedwait().
    
    Signed-off-by: Chengdong Wang <[email protected]>
---
 sched/signal/CMakeLists.txt                       |   1 +
 sched/signal/Make.defs                            |   2 +-
 sched/signal/{sig_timedwait.c => sig_clockwait.c} | 247 +---------------------
 sched/signal/sig_timedwait.c                      | 231 --------------------
 4 files changed, 3 insertions(+), 478 deletions(-)

diff --git a/sched/signal/CMakeLists.txt b/sched/signal/CMakeLists.txt
index 9db325fec5e..31c32c44a10 100644
--- a/sched/signal/CMakeLists.txt
+++ b/sched/signal/CMakeLists.txt
@@ -33,6 +33,7 @@ if(NOT CONFIG_DISABLE_ALL_SIGNALS)
       sig_notification.c
       sig_dispatch.c
       sig_pause.c
+      sig_clockwait.c
       sig_nanosleep.c
       sig_usleep.c
       sig_sleep.c
diff --git a/sched/signal/Make.defs b/sched/signal/Make.defs
index b70ac2a8246..7117c527655 100644
--- a/sched/signal/Make.defs
+++ b/sched/signal/Make.defs
@@ -23,7 +23,7 @@ ifneq ($(CONFIG_DISABLE_ALL_SIGNALS),y)
 CSRCS += sig_dispatch.c sig_kill.c sig_lowest.c sig_nanosleep.c
 CSRCS += sig_notification.c sig_pause.c sig_ppoll.c sig_procmask.c
 CSRCS += sig_pselect.c sig_queue.c sig_sleep.c sig_suspend.c sig_tgkill.c
-CSRCS += sig_timedwait.c sig_usleep.c sig_waitinfo.c
+CSRCS += sig_timedwait.c sig_usleep.c sig_waitinfo.c sig_clockwait.c
 endif
 
 ifeq ($(CONFIG_ENABLE_ALL_SIGNALS),y)
diff --git a/sched/signal/sig_timedwait.c b/sched/signal/sig_clockwait.c
similarity index 53%
copy from sched/signal/sig_timedwait.c
copy to sched/signal/sig_clockwait.c
index d3f63506694..92a6859d7db 100644
--- a/sched/signal/sig_timedwait.c
+++ b/sched/signal/sig_clockwait.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * sched/signal/sig_timedwait.c
+ * sched/signal/sig_clockwait.c
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -289,248 +289,3 @@ int nxsig_clockwait(int clockid, int flags,
 
   return 0;
 }
-
-/****************************************************************************
- * Name: nxsig_timedwait
- *
- * Description:
- *   This function selects the pending signal set specified by the argument
- *   set.  If multiple signals are pending in set, it will remove and return
- *   the lowest numbered one.  If no signals in set are pending at the time
- *   of the call, the calling process will be suspended until one of the
- *   signals in set becomes pending, OR until the process is interrupted by
- *   an unblocked signal, OR until the time interval specified by timeout
- *   (if any), has expired. If timeout is NULL, then the timeout interval
- *   is forever.
- *
- *   If the info argument is non-NULL, the selected signal number is stored
- *   in the si_signo member and the cause of the signal is stored in the
- *   si_code member.  The content of si_value is only meaningful if the
- *   signal was generated by sigqueue() (or nxsig_queue).
- *
- *   This is an internal OS interface.  It is functionally equivalent to
- *   sigtimedwait() except that:
- *
- *   - It is not a cancellation point, and
- *   - It does not modify the errno value.
- *
- * Input Parameters:
- *   set     - The pending signal set.
- *   info    - The returned value (may be NULL).
- *   timeout - The amount of time to wait (may be NULL)
- *
- * Returned Value:
- *   This is an internal OS interface and should not be used by applications.
- *   It follows the NuttX internal error return policy:  Zero (OK) is
- *   returned on success.  A negated errno value is returned on failure.
- *
- *   EAGAIN - No signal specified by set was generated within the specified
- *            timeout period.
- *   EINTR  - The wait was interrupted by an unblocked, caught signal.
- *
- ****************************************************************************/
-
-int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
-                    FAR const struct timespec *timeout)
-{
-  FAR struct tcb_s *rtcb;
-#ifdef CONFIG_ENABLE_ALL_SIGNALS
-  sigset_t intersection;
-  FAR sigpendq_t *sigpend;
-#endif
-  irqstate_t flags;
-  siginfo_t unbinfo;
-  int ret;
-
-  DEBUGASSERT(set != NULL && up_interrupt_context() == false);
-
-  /* Several operations must be performed below:  We must determine if any
-   * signal is pending and, if not, wait for the signal.  Since signals can
-   * be posted from the interrupt level, there is a race condition that
-   * can only be eliminated by disabling interrupts!
-   */
-
-  flags = enter_critical_section();
-  rtcb  = this_task();
-
-#ifdef CONFIG_ENABLE_ALL_SIGNALS
-  /* Check if there is a pending signal corresponding to one of the
-   * signals in the pending signal set argument.
-   */
-
-  intersection = nxsig_pendingset(rtcb);
-  sigandset(&intersection, &intersection, set);
-  if (!sigisemptyset(&intersection))
-    {
-      /* One or more of the signals in intersections is sufficient to cause
-       * us to not wait.  Pick the lowest numbered signal and mark it not
-       * pending.
-       */
-
-      sigpend = nxsig_remove_pendingsignal(rtcb,
-                                           nxsig_lowest(&intersection));
-      DEBUGASSERT(sigpend);
-
-      /* Return the signal info to the caller if so requested */
-
-      if (info != NULL)
-        {
-          memcpy(info, &sigpend->info, sizeof(struct siginfo));
-        }
-
-      /* The return value is the number of the signal that awakened us */
-
-      ret = sigpend->info.si_signo;
-
-      /* Then dispose of the pending signal structure properly */
-
-      nxsig_release_pendingsignal(sigpend);
-    }
-
-  /* We will have to wait for a signal to be posted to this task. */
-
-  else
-#endif
-    {
-      rtcb->sigunbinfo = (info == NULL) ? &unbinfo : info;
-
-      /* Save the set of pending signals to wait for */
-
-      rtcb->sigwaitmask = *set;
-
-      leave_critical_section(flags);
-
-      ret = nxsig_clockwait(CLOCK_REALTIME, 0, timeout, NULL);
-      if (ret < 0)
-        {
-          rtcb->sigunbinfo = NULL;
-          return ret;
-        }
-
-      flags = enter_critical_section();
-
-      /* We are running again, clear the sigwaitmask */
-
-      sigemptyset(&rtcb->sigwaitmask);
-
-      /* When we awaken, the cause will be in the TCB.  Get the signal number
-       * or timeout) that awakened us.
-       */
-
-      if (GOOD_SIGNO(rtcb->sigunbinfo->si_signo))
-        {
-          /* We were awakened by a signal... but is it one of the signals
-           * that we were waiting for?
-           */
-
-          if (nxsig_ismember(set, rtcb->sigunbinfo->si_signo) == 1)
-            {
-              /* Yes.. the return value is the number of the signal that
-               * awakened us.
-               */
-
-              ret = rtcb->sigunbinfo->si_signo;
-            }
-          else
-            {
-              /* No... then report the EINTR error */
-
-              ret = -EINTR;
-            }
-        }
-      else
-        {
-          /* Otherwise, we must have been awakened by the timeout or,
-           * perhaps, the wait was cancelled.
-           */
-
-#ifdef CONFIG_CANCELLATION_POINTS
-          if (rtcb->sigunbinfo->si_signo == SIG_CANCEL_TIMEOUT)
-            {
-              /* The wait was canceled */
-
-              ret = -rtcb->sigunbinfo->si_errno;
-              DEBUGASSERT(ret < 0);
-            }
-          else
-#endif
-            {
-              /* We were awakened by a timeout.  Set EAGAIN and return an
-               * error.
-               */
-
-              DEBUGASSERT(rtcb->sigunbinfo->si_signo == SIG_WAIT_TIMEOUT);
-              ret = -EAGAIN;
-            }
-        }
-
-      rtcb->sigunbinfo = NULL;
-    }
-
-  leave_critical_section(flags);
-
-  return ret;
-}
-
-/****************************************************************************
- * Name: sigtimedwait
- *
- * Description:
- *   This function selects the pending signal set specified by the argument
- *   set.  If multiple signals are pending in set, it will remove and return
- *   the lowest numbered one.  If no signals in set are pending at the time
- *   of the call, the calling process will be suspended until one of the
- *   signals in set becomes pending, OR until the process is interrupted by
- *   an unblocked signal, OR until the time interval specified by timeout
- *   (if any), has expired. If timeout is NULL, then the timeout interval
- *   is forever.
- *
- *   If the info argument is non-NULL, the selected signal number is stored
- *   in the si_signo member and the cause of the signal is stored in the
- *   si_code member.  The content of si_value is only meaningful if the
- *   signal was generated by sigqueue().
- *
- *   The following values for si_code are defined in signal.h:
- *     SI_USER    - Signal sent from kill, raise, or abort
- *     SI_QUEUE   - Signal sent from sigqueue
- *     SI_TIMER   - Signal is result of timer expiration
- *     SI_ASYNCIO - Signal is the result of asynch IO completion
- *     SI_MESGQ   - Signal generated by arrival of a message on an
- *                  empty message queue.
- *
- * Input Parameters:
- *   set     - The pending signal set.
- *   info    - The returned value (may be NULL).
- *   timeout - The amount of time to wait (may be NULL)
- *
- * Returned Value:
- *   Signal number that cause the wait to be terminated, otherwise -1 (ERROR)
- *   is returned with errno set to either:
- *
- *   EAGAIN - No signal specified by set was generated within the specified
- *            timeout period.
- *   EINTR  - The wait was interrupted by an unblocked, caught signal.
- *
- ****************************************************************************/
-
-int sigtimedwait(FAR const sigset_t *set, FAR struct siginfo *info,
-                 FAR const struct timespec *timeout)
-{
-  int ret;
-
-  /* sigtimedwait() is a cancellation point */
-
-  enter_cancellation_point();
-
-  /* Let nxsig_timedwait() do the work. */
-
-  ret = nxsig_timedwait(set, info, timeout);
-  if (ret < 0)
-    {
-      set_errno(-ret);
-      ret = ERROR;
-    }
-
-  leave_cancellation_point();
-  return ret;
-}
diff --git a/sched/signal/sig_timedwait.c b/sched/signal/sig_timedwait.c
index d3f63506694..e6024702be3 100644
--- a/sched/signal/sig_timedwait.c
+++ b/sched/signal/sig_timedwait.c
@@ -55,241 +55,10 @@
  * Private Functions
  ****************************************************************************/
 
-/****************************************************************************
- * Name: nxsig_timeout
- *
- * Description:
- *   A timeout elapsed while waiting for signals to be queued.
- *
- * Assumptions:
- *   This function executes in the context of the timer interrupt handler.
- *   Local interrupts are assumed to be disabled on entry.
- *
- ****************************************************************************/
-
-static void nxsig_timeout(wdparm_t arg)
-{
-  FAR struct tcb_s *wtcb = (FAR struct tcb_s *)(uintptr_t)arg;
-
-  irqstate_t flags;
-
-  /* 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)
-    {
-      nxsig_wait_irq(wtcb, SIG_WAIT_TIMEOUT, SI_TIMER, ETIMEDOUT);
-    }
-
-  leave_critical_section(flags);
-}
-
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
-/****************************************************************************
- * Name: nxsig_wait_irq
- *
- * Description:
- *   An error event has occurred and the signal wait must be terminated with
- *   an error.
- *
- ****************************************************************************/
-
-void nxsig_wait_irq(FAR struct tcb_s *wtcb, uint8_t signo,
-                    uint8_t code, int errcode)
-{
-  FAR struct tcb_s *rtcb = this_task();
-
-  if (wtcb->sigunbinfo != NULL)
-    {
-      wtcb->sigunbinfo->si_signo           = signo;
-      wtcb->sigunbinfo->si_code            = code;
-      wtcb->sigunbinfo->si_errno           = errcode;
-      wtcb->sigunbinfo->si_value.sival_int = 0;
-#ifdef CONFIG_SCHED_HAVE_PARENT
-      wtcb->sigunbinfo->si_pid             = 0;  /* Not applicable */
-      wtcb->sigunbinfo->si_status          = OK;
-#endif
-    }
-
-  /* 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);
-    }
-}
-
-/****************************************************************************
- * Name: nxsig_clockwait
- *
- * Description:
- *   This function selects the pending signal set specified by the argument
- *   set.  If multiple signals are pending in set, it will remove and return
- *   the lowest numbered one.  If no signals in set are pending at the time
- *   of the call, the calling process will be suspended until one of the
- *   signals in set becomes pending, OR until the process is interrupted by
- *   an unblocked signal, OR until the time interval specified by timeout
- *   (if any), has expired. If timeout is NULL, then the timeout interval
- *   is forever.
- *
- *   If the info argument is non-NULL, the selected signal number is stored
- *   in the si_signo member and the cause of the signal is stored in the
- *   si_code member.  The content of si_value is only meaningful if the
- *   signal was generated by sigqueue() (or nxsig_queue).
- *
- *   This is an internal OS interface.  It is functionally equivalent to
- *   sigtimedwait() except that:
- *
- *   - It is not a cancellation point, and
- *   - It does not modify the errno value.
- *
- * Input Parameters:
- *   clockid - The ID of the clock to be used to measure the timeout.
- *   flags   - Open flags.  TIMER_ABSTIME  is the only supported flag.
- *   rqtp - The amount of time to be suspended from execution.
- *   rmtp - If the rmtp argument is non-NULL, the timespec structure
- *          referenced by it is updated to contain the amount of time
- *          remaining in the interval (the requested time minus the time
- *          actually slept)
- *
- * Returned Value:
- *   This is an internal OS interface and should not be used by applications.
- *   A negated errno value is returned on failure.
- *
- *   EAGAIN - wait time is zero.
- *   EINTR  - The wait was interrupted by an unblocked, caught signal.
- *
- * Notes:
- *  This function should be called with critical section set.
- *
- ****************************************************************************/
-
-int nxsig_clockwait(int clockid, int flags,
-                    FAR const struct timespec *rqtp,
-                    FAR struct timespec *rmtp)
-{
-  FAR struct tcb_s *rtcb;
-  irqstate_t        iflags;
-  clock_t expect = 0u;
-  clock_t stop   = 0u;
-
-  if (rqtp && (rqtp->tv_nsec < 0 || rqtp->tv_nsec >= 1000000000))
-    {
-      return -EINVAL;
-    }
-
-  /* If rqtp is zero, yield CPU and return
-   * Notice: The behavior of sleep(0) is not defined in POSIX, so there are
-   * different implementations:
-   * 1. In Linux, nanosleep(0) will call schedule() to yield CPU:
-   *    https://elixir.bootlin.com/linux/latest/source/kernel/time/
-   *    hrtimer.c#L2038
-   * 2. In BSD, nanosleep(0) will return immediately:
-   *    https://github.com/freebsd/freebsd-src/blob/
-   *    475fa89800086718bd9249fd4dc3f862549f1f78/crypto/openssh/
-   *    openbsd-compat/bsd-misc.c#L243
-   */
-
-  if (rqtp && rqtp->tv_sec == 0 && rqtp->tv_nsec == 0)
-    {
-      sched_yield();
-      return -EAGAIN;
-    }
-
-#ifdef CONFIG_CANCELLATION_POINTS
-  /* nxsig_clockwait() is not a cancellation point, but it may be called
-   * from a cancellation point.  So if a cancellation is pending, we
-   * must exit immediately without waiting.
-   */
-
-  if (check_cancellation_point())
-    {
-      /* If there is a pending cancellation, then do not perform
-       * the wait.  Exit now with ECANCELED.
-       */
-
-      return -ECANCELED;
-    }
-#endif
-
-  iflags = enter_critical_section();
-  rtcb = this_task();
-
-  if (rqtp)
-    {
-      /* Start the watchdog timer */
-
-      if ((flags & TIMER_ABSTIME) == 0)
-        {
-          expect = clock_delay2abstick(clock_time2ticks(rqtp));
-        }
-      else if (clockid == CLOCK_REALTIME)
-        {
-#ifdef CONFIG_CLOCK_TIMEKEEPING
-          clock_t delay;
-
-          clock_abstime2ticks(CLOCK_REALTIME, rqtp, &delay);
-          expect = clock_delay2abstick(delay);
-#else
-          clock_realtime2absticks(rqtp, &expect);
-#endif
-        }
-      else
-        {
-          expect = clock_time2ticks(rqtp);
-        }
-
-        wd_start_abstick(&rtcb->waitdog, expect,
-                         nxsig_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, list_waitingforsignal());
-
-  /* Now, perform the context switch if one is needed */
-
-  up_switch_context(this_task(), rtcb);
-
-  /* We no longer need the watchdog */
-
-  if (rqtp)
-    {
-      stop = clock_systime_ticks();
-    }
-
-  leave_critical_section(iflags);
-
-  if (rqtp && rmtp && expect)
-    {
-      clock_ticks2time(rmtp,
-                       clock_compare(stop, expect) ? expect - stop : 0);
-    }
-
-  return 0;
-}
-
 /****************************************************************************
  * Name: nxsig_timedwait
  *

Reply via email to