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 758e88672b Assert if a thread attempts to post a semaphore incorrectly.
758e88672b is described below

commit 758e88672b703bcb0d1251ae9731b2ec295e81c0
Author: Gregory Nutt <[email protected]>
AuthorDate: Fri Mar 31 16:25:45 2023 -0600

    Assert if a thread attempts to post a semaphore incorrectly.
    
    Assert in nxsem_post if:
    
    - Priority inheritance is enabled on a semaphore
    - A thread that does not hold the semaphore attempts to post it
    
    This will detect an error condition described in 
https://cwiki.apache.org/confluence/display/NUTTX/Signaling+Semaphores+and+Priority+Inheritance
    
    None.  The debug instrumentation is only enabled if CONFIG_DEBUG_ASSERTIONS 
is enabled.
    
    Use sim:ostest.  Verify that no assertions occur.
---
 sched/semaphore/sem_holder.c | 59 ++++++++++++++++++++++++++++++++++++++++++++
 sched/semaphore/sem_post.c   |  6 +++++
 sched/semaphore/semaphore.h  |  6 +++++
 3 files changed, 71 insertions(+)

diff --git a/sched/semaphore/sem_holder.c b/sched/semaphore/sem_holder.c
index d012c78fe5..9e0f2c607a 100644
--- a/sched/semaphore/sem_holder.c
+++ b/sched/semaphore/sem_holder.c
@@ -28,6 +28,7 @@
 #include <assert.h>
 #include <debug.h>
 #include <nuttx/arch.h>
+#include <arch/irq.h>
 
 #include "sched/sched.h"
 #include "semaphore/semaphore.h"
@@ -1058,4 +1059,62 @@ void nxsem_release_all(FAR struct tcb_s *htcb)
     }
 }
 
+/****************************************************************************
+ * Name: nxsem_isholder
+ *
+ * Assertion helper for sem_post().  If priority inheritance is enabled
+ * assure that the calling thread is the same as the holder thread.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ASSERTIONS
+bool nxsem_checkholder(FAR sem_t *sem)
+{
+  FAR struct tcb_s *htcb;
+  pid_t tid;
+
+  /* Is priorty inheritance selected? */
+
+  if ((sem->flags & SEM_PRIO_MASK) != SEM_PRIO_INHERIT)
+    {
+      return true;
+    }
+
+  /* Get the thread ID.  Skip thread ID 0; that is the IDLE thread which
+   * normally does not take semaphores but may do so initially as part of
+   * OS bringup.
+   */
+
+  tid = gettid();
+  if (tid == 0)
+    {
+      return true;
+    }
+
+  /* A semaphore with priority inheritance enabled cannot be called from an
+   * interrupt handler.  There is no valid holder information available in
+   * the interrupt context.
+   */
+
+  if (up_interrupt_context())
+    {
+      return false;
+    }
+
+  /* Get the TCB associated with this thread */
+
+  htcb = nxsched_get_tcb(tid);
+  if (htcb == NULL)
+    {
+      return false;
+    }
+
+  /* Return FALSE is the thread of this TCB is not a holder of this
+   * semaphore.
+   */
+
+  return nxsem_findholder(sem, htcb) != NULL;
+}
+#endif /* CONFIG_DEBUG_ASSERTIONS */
+
 #endif /* CONFIG_PRIORITY_INHERITANCE */
diff --git a/sched/semaphore/sem_post.c b/sched/semaphore/sem_post.c
index 6c721d27b0..f6c5e92393 100644
--- a/sched/semaphore/sem_post.c
+++ b/sched/semaphore/sem_post.c
@@ -78,6 +78,12 @@ int nxsem_post(FAR sem_t *sem)
 
   DEBUGASSERT(sem != NULL);
 
+  /* If priority inheritance is enabled assure that the calling thread is
+   * the same as the holder thread.
+   */
+
+  DEBUGASSERT(nxsem_checkholder(sem));
+
   /* The following operations must be performed with interrupts
    * disabled because sem_post() may be called from an interrupt
    * handler.
diff --git a/sched/semaphore/semaphore.h b/sched/semaphore/semaphore.h
index 7a24f5e696..3f7b4a9375 100644
--- a/sched/semaphore/semaphore.h
+++ b/sched/semaphore/semaphore.h
@@ -91,6 +91,12 @@ void nxsem_release_all(FAR struct tcb_s *stcb);
 #  define nxsem_release_all(stcb)
 #endif
 
+#if defined(CONFIG_DEBUG_ASSERTIONS) && defined(CONFIG_PRIORITY_INHERITANCE)
+bool nxsem_checkholder(FAR sem_t *sem);
+#else
+#  define nxsem_checkholder(sem) true
+#endif /* CONFIG_DEBUG_ASSERTIONS */
+
 #undef EXTERN
 #ifdef __cplusplus
 }

Reply via email to