summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-03-13 11:27:34 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-03-13 11:27:34 +0000
commit145f2bf35bfc0e1dabae83cb78413483b01ede0b (patch)
tree4e4b962b36db85ea0a4374d3889d2937df9a322f
parentdbade675fdd1f84f620d0cda54caf0f23953733c (diff)
downloadnuttx-145f2bf35bfc0e1dabae83cb78413483b01ede0b.tar.gz
nuttx-145f2bf35bfc0e1dabae83cb78413483b01ede0b.tar.bz2
nuttx-145f2bf35bfc0e1dabae83cb78413483b01ede0b.zip
Free holder containers on sem_destroy
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1598 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/sched/sem_holder.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/nuttx/sched/sem_holder.c b/nuttx/sched/sem_holder.c
index 21440752f..1388965be 100644
--- a/nuttx/sched/sem_holder.c
+++ b/nuttx/sched/sem_holder.c
@@ -245,6 +245,15 @@ static int sem_foreachholder(FAR sem_t *sem, holderhandler_t handler, FAR void *
}
/****************************************************************************
+ * Name: sem_recoverholders
+ ****************************************************************************/
+
+static int sem_recoverholders(struct semholder_s *pholder, FAR sem_t *sem, FAR void *arg)
+{
+ sem_freeholder(sem, pholder);
+}
+
+/****************************************************************************
* Name: sem_boostholderprio
****************************************************************************/
@@ -354,6 +363,11 @@ static int sem_verifyholder(struct semholder_s *pholder, FAR sem_t *sem, FAR voi
{
FAR _TCB *htcb = (FAR _TCB *)pholder->holder;
+ /* Called after a semaphore has been released (incremented), the semaphore
+ * could is non-negative, and there is no thread waiting for the count.
+ * In this case, the priority of the holder should not be boosted.
+ */
+
#if CONFIG_SEM_NNESTPRIO > 0
DEBUGASSERT(htcb->npend_reprio == 0);
#endif
@@ -536,23 +550,32 @@ void sem_initholders(void)
void sem_destroyholder(FAR sem_t *sem)
{
-#if 0
FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
/* It is an error is a semaphore is destroyed while there are any holders
* (except perhaps the thread releas the semaphore itself). Hmmm.. but
* we actually have to assume that the caller knows what it is doing because
* could have killed another thread that is the actual holder of the semaphore.
+ * We cannot make any assumptions about the state of the semaphore or the
+ * state of any of the holder threads.
+ *
+ * So just recover any stranded holders and hope the task knows what it is
+ * doing.
*/
#if CONFIG_SEM_PREALLOCHOLDERS > 0
- DEBUGASSERT((!sem->hlist.holder || sem->hlist.holder == rtcb) && !sem->hlist.flink);
+ if (sem->hlist.holder || sem->hlist.flink)
+ {
+ sdbg("Semaphore destroyed with holders\n");
+ (void)sem_foreachholder(sem, sem_recoverholders, NULL);
+ }
#else
- DEBUGASSERT(!sem->hlist.holder || sem->hlist.holder == rtcb);
-#endif
-#endif
-
+ if (sem->hlist.holder)
+ {
+ sdbg("Semaphore destroyed with holder\n");
+ }
sem->hlist.holder = NULL;
+#endif
}
/****************************************************************************