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
}