You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ag...@apache.org on 2020/06/15 20:21:27 UTC

[incubator-nuttx] branch master updated (4a72bcc -> 4d634b9)

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

aguettouche pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.


    from 4a72bcc  boards/arm/s32k1xx/rddrone-uavcan146/configs/nsh/defconfig: Refresh the config.
     new 2160a65  sched: Don't call nxnotify_cancellation in task_setcancelstate
     new 4d634b9  sched: Consolidate the cancellation notification logic

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 sched/pthread/pthread_cancel.c   | 50 +-------------------
 sched/signal/sig_default.c       | 53 +---------------------
 sched/task/Make.defs             |  6 +--
 sched/task/task.h                |  4 +-
 sched/task/task_cancelpt.c       | 98 ++++++++++++++++++++++++++++------------
 sched/task/task_delete.c         | 50 +-------------------
 sched/task/task_setcancelstate.c | 13 +-----
 7 files changed, 78 insertions(+), 196 deletions(-)


[incubator-nuttx] 02/02: sched: Consolidate the cancellation notification logic

Posted by ag...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 4d634b9006760555c48ce70375190dc57fb594e2
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Sun Jun 7 00:41:47 2020 +0800

    sched: Consolidate the cancellation notification logic
    
    to avoid the code duplication
    
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
    Change-Id: Ie2ba55c382eb3eb7c8d9f04bba1b9e294aaf6196
---
 sched/pthread/pthread_cancel.c | 50 +--------------------
 sched/signal/sig_default.c     | 53 +----------------------
 sched/task/Make.defs           |  6 +--
 sched/task/task.h              |  4 +-
 sched/task/task_cancelpt.c     | 98 +++++++++++++++++++++++++++++-------------
 sched/task/task_delete.c       | 50 +--------------------
 6 files changed, 77 insertions(+), 184 deletions(-)

diff --git a/sched/pthread/pthread_cancel.c b/sched/pthread/pthread_cancel.c
index 02b8087..dcc58f6 100644
--- a/sched/pthread/pthread_cancel.c
+++ b/sched/pthread/pthread_cancel.c
@@ -67,61 +67,15 @@ int pthread_cancel(pthread_t thread)
   DEBUGASSERT((tcb->flags & TCB_FLAG_TTYPE_MASK) ==
                TCB_FLAG_TTYPE_PTHREAD);
 
-  /* Check to see if this thread has the non-cancelable bit set in its
-   * flags. Suppress context changes for a bit so that the flags are stable.
-   * (the flags should not change in interrupt handling).
-   */
-
-  sched_lock();
-  if ((tcb->flags & TCB_FLAG_NONCANCELABLE) != 0)
-    {
-      /* Then we cannot cancel the thread now.  Here is how this is
-       * supposed to work:
-       *
-       * "When cancellability is disabled, all cancels are held pending
-       *  in the target thread until the thread changes the cancellability.
-       *  When cancellability is deferred, all cancels are held pending in
-       *  the target thread until the thread changes the cancellability,
-       *  calls a function which is a cancellation point or calls
-       *  pthread_testcancel(), thus creating a cancellation point. When
-       *  cancellability is asynchronous, all cancels are acted upon
-       *  immediately, interrupting the thread with its processing."
-       */
-
-      tcb->flags |= TCB_FLAG_CANCEL_PENDING;
-      sched_unlock();
-      return OK;
-    }
-
-#ifdef CONFIG_CANCELLATION_POINTS
-  /* Check if this thread supports deferred cancellation */
+  /* Notify the target if the non-cancelable or deferred cancellation set */
 
-  if ((tcb->flags & TCB_FLAG_CANCEL_DEFERRED) != 0)
+  if (nxnotify_cancellation(tcb))
     {
-      /* Then we cannot cancel the thread asynchronously.  Mark the
-       * cancellation as pending.
-       */
-
-      tcb->flags |= TCB_FLAG_CANCEL_PENDING;
-
-      /* If the thread is waiting at a cancellation point, then notify of the
-       * cancellation thereby waking the task up with an ECANCELED error.
-       */
-
-      if (tcb->cpcount > 0)
-        {
-          nxnotify_cancellation(tcb);
-        }
-
-      sched_unlock();
       return OK;
     }
-#endif
 
   /* Otherwise, perform the asyncrhonous cancellation */
 
-  sched_unlock();
-
   /* Check to see if the ID refers to ourselves.. this would be the
    * same as pthread_exit(PTHREAD_CANCELED).
    */
diff --git a/sched/signal/sig_default.c b/sched/signal/sig_default.c
index 28bad31..70a2238 100644
--- a/sched/signal/sig_default.c
+++ b/sched/signal/sig_default.c
@@ -207,61 +207,12 @@ static void nxsig_abnormal_termination(int signo)
 {
   FAR struct tcb_s *rtcb = (FAR struct tcb_s *)this_task();
 
-  /* Check to see if this task has the non-cancelable bit set in its
-   * flags. Suppress context changes for a bit so that the flags are stable.
-   * (the flags should not change in interrupt handling).
-   */
-
-  sched_lock();
-  if ((rtcb->flags & TCB_FLAG_NONCANCELABLE) != 0)
-    {
-      /* Then we cannot cancel the thread now.  Here is how this is
-       * supposed to work:
-       *
-       * "When cancellability is disabled, all cancels are held pending
-       *  in the target thread until the thread changes the cancellability.
-       *  When cancellability is deferred, all cancels are held pending in
-       *  the target thread until the thread changes the cancellability,
-       *  calls a function which is a cancellation point or calls
-       *  pthread_testcancel(), thus creating a cancellation point.  When
-       *  cancellability is asynchronous, all cancels are acted upon
-       *  immediately, interrupting the thread with its processing."
-       *
-       * REVISIT:  Does this rule apply to equally to both SIGKILL and
-       * SIGINT?
-       */
-
-      rtcb->flags |= TCB_FLAG_CANCEL_PENDING;
-      sched_unlock();
-      return;
-    }
-
-#ifdef CONFIG_CANCELLATION_POINTS
-  /* Check if this task supports deferred cancellation */
+  /* Notify the target if the non-cancelable or deferred cancellation set */
 
-  if ((rtcb->flags & TCB_FLAG_CANCEL_DEFERRED) != 0)
+  if (nxnotify_cancellation(rtcb))
     {
-      /* Then we cannot cancel the task asynchronously.
-       * Mark the cancellation as pending.
-       */
-
-      rtcb->flags |= TCB_FLAG_CANCEL_PENDING;
-
-      /* If the task is waiting at a cancellation point, then notify of the
-       * cancellation thereby waking the task up with an ECANCELED error.
-       */
-
-      if (rtcb->cpcount > 0)
-        {
-          nxnotify_cancellation(rtcb);
-        }
-
-      sched_unlock();
       return;
     }
-#endif
-
-  sched_unlock();
 
   /* Careful:  In the multi-threaded task, the signal may be handled on a
    * child pthread.
diff --git a/sched/task/Make.defs b/sched/task/Make.defs
index a5c2295..1fa00c7 100644
--- a/sched/task/Make.defs
+++ b/sched/task/Make.defs
@@ -37,7 +37,7 @@ CSRCS += task_create.c task_init.c task_setup.c task_activate.c
 CSRCS += task_start.c task_delete.c task_exit.c task_exithook.c
 CSRCS += task_getgroup.c task_getpid.c task_prctl.c task_recover.c
 CSRCS += task_restart.c task_spawnparms.c task_setcancelstate.c
-CSRCS += task_terminate.c exit.c
+CSRCS += task_cancelpt.c task_terminate.c exit.c
 
 ifeq ($(CONFIG_ARCH_HAVE_VFORK),y)
 ifeq ($(CONFIG_SCHED_WAITPID),y)
@@ -71,10 +71,6 @@ ifeq ($(CONFIG_SCHED_ONEXIT),y)
 CSRCS += task_onexit.c
 endif
 
-ifeq ($(CONFIG_CANCELLATION_POINTS),y)
-CSRCS += task_cancelpt.c
-endif
-
 # Include task build support
 
 DEPPATH += --dep-path task
diff --git a/sched/task/task.h b/sched/task/task.h
index 80279a7..3de2d42 100644
--- a/sched/task/task.h
+++ b/sched/task/task.h
@@ -71,8 +71,6 @@ void nxtask_recover(FAR struct tcb_s *tcb);
 
 /* Cancellation points */
 
-#ifdef CONFIG_CANCELLATION_POINTS
-void nxnotify_cancellation(FAR struct tcb_s *tcb);
-#endif
+bool nxnotify_cancellation(FAR struct tcb_s *tcb);
 
 #endif /* __SCHED_TASK_TASK_H */
diff --git a/sched/task/task_cancelpt.c b/sched/task/task_cancelpt.c
index 988e9bf..cad59df 100644
--- a/sched/task/task_cancelpt.c
+++ b/sched/task/task_cancelpt.c
@@ -316,6 +316,8 @@ bool check_cancellation_point(void)
   return ret;
 }
 
+#endif /* CONFIG_CANCELLATION_POINTS */
+
 /****************************************************************************
  * Name: nxnotify_cancellation
  *
@@ -327,9 +329,12 @@ bool check_cancellation_point(void)
  *   leave_cancellation_point() would then follow, causing the thread to
  *   exit.
  *
+ * Returned Value:
+ *   Indicate whether the notification delivery to the target
+ *
  ****************************************************************************/
 
-void nxnotify_cancellation(FAR struct tcb_s *tcb)
+bool nxnotify_cancellation(FAR struct tcb_s *tcb)
 {
   irqstate_t flags;
 
@@ -339,51 +344,86 @@ void nxnotify_cancellation(FAR struct tcb_s *tcb)
 
   flags = enter_critical_section();
 
-  /* Make sure that the cancellation pending indication is set. */
-
-  tcb->flags |= TCB_FLAG_CANCEL_PENDING;
-
   /* We only notify the cancellation if (1) the thread has not disabled
    * cancellation, (2) the thread uses the deferred cancellation mode,
    * (3) the thread is waiting within a cancellation point.
    */
 
-  if (((tcb->flags & TCB_FLAG_NONCANCELABLE) == 0 &&
-       (tcb->flags & TCB_FLAG_CANCEL_DEFERRED) != 0) ||
-      tcb->cpcount > 0)
+  /* Check to see if this task has the non-cancelable bit set. */
+
+  if ((tcb->flags & TCB_FLAG_NONCANCELABLE) != 0)
     {
-      /* If the thread is blocked waiting for a semaphore, then the thread
-       * must be unblocked to handle the cancellation.
+      /* Then we cannot cancel the thread now.  Here is how this is
+       * supposed to work:
+       *
+       * "When cancellability is disabled, all cancels are held pending
+       *  in the target thread until the thread changes the cancellability.
+       *  When cancellability is deferred, all cancels are held pending in
+       *  the target thread until the thread changes the cancellability,
+       *  calls a function which is a cancellation point or calls
+       *  pthread_testcancel(), thus creating a cancellation point.  When
+       *  cancellability is asynchronous, all cancels are acted upon
+       *  immediately, interrupting the thread with its processing."
        */
 
-      if (tcb->task_state == TSTATE_WAIT_SEM)
-        {
-          nxsem_wait_irq(tcb, ECANCELED);
-        }
+      tcb->flags |= TCB_FLAG_CANCEL_PENDING;
+      leave_critical_section(flags);
+      return true;
+    }
+
+#ifdef CONFIG_CANCELLATION_POINTS
+  /* Check if this task supports deferred cancellation */
 
-      /* If the thread is blocked waiting on a signal, then the
-       * thread must be unblocked to handle the cancellation.
+  if ((tcb->flags & TCB_FLAG_CANCEL_DEFERRED) != 0)
+    {
+      /* Then we cannot cancel the task asynchronously.
+       * Mark the cancellation as pending.
        */
 
-      else if (tcb->task_state == TSTATE_WAIT_SIG)
-        {
-          nxsig_wait_irq(tcb, ECANCELED);
-        }
+      tcb->flags |= TCB_FLAG_CANCEL_PENDING;
 
-#ifndef CONFIG_DISABLE_MQUEUE
-      /* If the thread is blocked waiting on a message queue, then the
-       * thread must be unblocked to handle the cancellation.
+      /* If the task is waiting at a cancellation point, then notify of the
+       * cancellation thereby waking the task up with an ECANCELED error.
        */
 
-      else if (tcb->task_state == TSTATE_WAIT_MQNOTEMPTY ||
-               tcb->task_state == TSTATE_WAIT_MQNOTFULL)
+      if (tcb->cpcount > 0)
         {
-          nxmq_wait_irq(tcb, ECANCELED);
-        }
+          /* If the thread is blocked waiting for a semaphore, then the
+           * thread must be unblocked to handle the cancellation.
+           */
+
+          if (tcb->task_state == TSTATE_WAIT_SEM)
+            {
+              nxsem_wait_irq(tcb, ECANCELED);
+            }
+
+          /* If the thread is blocked waiting on a signal, then the
+           * thread must be unblocked to handle the cancellation.
+           */
+
+          else if (tcb->task_state == TSTATE_WAIT_SIG)
+            {
+              nxsig_wait_irq(tcb, ECANCELED);
+            }
+
+#ifndef CONFIG_DISABLE_MQUEUE
+          /* If the thread is blocked waiting on a message queue, then
+           * the thread must be unblocked to handle the cancellation.
+           */
+
+          else if (tcb->task_state == TSTATE_WAIT_MQNOTEMPTY ||
+                  tcb->task_state == TSTATE_WAIT_MQNOTFULL)
+            {
+              nxmq_wait_irq(tcb, ECANCELED);
+            }
 #endif
+        }
+
+      leave_critical_section(flags);
+      return true;
     }
+#endif
 
   leave_critical_section(flags);
+  return false;
 }
-
-#endif /* CONFIG_CANCELLATION_POINTS */
diff --git a/sched/task/task_delete.c b/sched/task/task_delete.c
index 8a6fe5b..eef94c1 100644
--- a/sched/task/task_delete.c
+++ b/sched/task/task_delete.c
@@ -143,59 +143,13 @@ int task_delete(pid_t pid)
       exit(EXIT_SUCCESS);
     }
 
-  /* Check to see if this task has the non-cancelable bit set in its
-   * flags. Suppress context changes for a bit so that the flags are stable.
-   * (the flags should not change in interrupt handling).
-   */
+  /* Notify the target if the non-cancelable or deferred cancellation set */
 
-  sched_lock();
-  if ((dtcb->flags & TCB_FLAG_NONCANCELABLE) != 0)
+  if (nxnotify_cancellation(dtcb))
     {
-      /* Then we cannot cancel the thread now.  Here is how this is
-       * supposed to work:
-       *
-       * "When cancellability is disabled, all cancels are held pending
-       *  in the target thread until the thread changes the cancellability.
-       *  When cancellability is deferred, all cancels are held pending in
-       *  the target thread until the thread changes the cancellability,
-       *  calls a function which is a cancellation point or calls
-       *  pthread_testcancel(), thus creating a cancellation point. When
-       *  cancellability is asynchronous, all cancels are acted upon
-       *  immediately, interrupting the thread with its processing."
-       */
-
-      dtcb->flags |= TCB_FLAG_CANCEL_PENDING;
-      sched_unlock();
       return OK;
     }
 
-#ifdef CONFIG_CANCELLATION_POINTS
-  /* Check if this task supports deferred cancellation */
-
-  if ((dtcb->flags & TCB_FLAG_CANCEL_DEFERRED) != 0)
-    {
-      /* Then we cannot cancel the task asynchronously.  Mark the
-       * cancellation as pending.
-       */
-
-      dtcb->flags |= TCB_FLAG_CANCEL_PENDING;
-
-      /* If the task is waiting at a cancellation point, then notify of the
-       * cancellation thereby waking the task up with an ECANCELED error.
-       */
-
-      if (dtcb->cpcount > 0)
-        {
-          nxnotify_cancellation(dtcb);
-        }
-
-      sched_unlock();
-      return OK;
-    }
-#endif
-
-  sched_unlock();
-
   /* Otherwise, perform the asynchronous cancellation, letting
    * nxtask_terminate() do all of the heavy lifting.
    */


[incubator-nuttx] 01/02: sched: Don't call nxnotify_cancellation in task_setcancelstate

Posted by ag...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 2160a6503021f6a71d4bc8764385c2f5a40db4fd
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Sun Jun 7 00:41:47 2020 +0800

    sched: Don't call nxnotify_cancellation in task_setcancelstate
    
    since it is impossible that the current running thread is
    in the waiting state and then need to wake up self.
    
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
    Change-Id: Ie2ba55c382eb3eb7c8d9f04bba1b9e294aaf6196
---
 sched/task/task_setcancelstate.c | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/sched/task/task_setcancelstate.c b/sched/task/task_setcancelstate.c
index 5c12969..070253d 100644
--- a/sched/task/task_setcancelstate.c
+++ b/sched/task/task_setcancelstate.c
@@ -114,18 +114,7 @@ int task_setcancelstate(int state, FAR int *oldstate)
 #ifdef CONFIG_CANCELLATION_POINTS
           /* If we are using deferred cancellation? */
 
-          if ((tcb->flags & TCB_FLAG_CANCEL_DEFERRED) != 0)
-            {
-              /* Yes.. If we are within a cancellation point, then
-               * notify of the cancellation.
-               */
-
-              if (tcb->cpcount > 0)
-                {
-                  nxnotify_cancellation(tcb);
-                }
-            }
-          else
+          if ((tcb->flags & TCB_FLAG_CANCEL_DEFERRED) == 0)
 #endif
             {
               /* No.. We are using asynchronous cancellation.  If the