Priority inheritance: When CONFIG_SEM_PREALLOCHOLDERS==0, there is only a single, hard-allocated holder structure. This is problem because in sem_wait() the holder is released, but needs to remain in the holder container until sem_restorebaseprio() is called. The call to sem_restorebaseprio() must be one of the last things the sem_wait() does because it can cause the task to be suspended. If in sem_wait(), a new task gets the semaphore count then it will fail to allocate the holder and will not participate in priority inheritance. This fix is to add two hard-allocated holders in the sem_t structure: One of the old holder and one for the new holder.

This commit is contained in:
Gregory Nutt
2017-03-10 09:30:15 -06:00
parent 769427ed5a
commit 360539afac
3 changed files with 68 additions and 28 deletions
+7 -5
View File
@@ -83,17 +83,19 @@ int sem_init(FAR sem_t *sem, int pshared, unsigned int value)
{
/* Initialize the seamphore count */
sem->semcount = (int16_t)value;
sem->semcount = (int16_t)value;
/* Initialize to support priority inheritance */
#ifdef CONFIG_PRIORITY_INHERITANCE
sem->flags = 0;
sem->flags = 0;
# if CONFIG_SEM_PREALLOCHOLDERS > 0
sem->hhead = NULL;
sem->hhead = NULL;
# else
sem->holder.htcb = NULL;
sem->holder.counts = 0;
sem->holder[0].htcb = NULL;
sem->holder[0].counts = 0;
sem->holder[1].htcb = NULL;
sem->holder[1].counts = 0;
# endif
#endif
return OK;