Nested semaphore locking

nobody wrote on Monday, March 06, 2006:

Hello,

is there any simple way to extend FreeRTOS
semaphores to add nesting?  Like in:

   xSemaphoreTake(s, portMAX_DELAY); /* obtains s */
   xSemaphoreTake(s, portMAX_DELAY); /* does not deadlock! */
   xSemaphoreGive(s); /* does not free s */
   xSemaphoreGive(s); /* really frees s */

I tried to implement it on top of FreeRTOS semaphores, but it’s quite tricky.

nobody wrote on Monday, March 06, 2006:

I’ve solved the problem like this.
Does it look sane?

typedef struct Semaphore
{
    xSemaphoreHandle lock;
    xTaskHandle      owner;
    int              nest_count;
} Semaphore;

void sem_obtain(struct Semaphore *s)
{
    if (s->owner != xTaskGetCurrentTaskHandle())
        xSemaphoreTake(s->lock, portMAX_DELAY);

    s->owner = xTaskGetCurrentTaskHandle();
    s->nest_count++;
}

void sem_release(struct Semaphore *s)
{
    ASSERT(s->owner == xTaskGetCurrentTaskHandle());

    if (–s->nest_count == 0)
    {
        /* Disown semaphore */
        s->owner = NULL;
        xSemaphoreGive(s->lock);
    }
}

nobody wrote on Monday, March 06, 2006:

Probably very sane, as I don’t really under stand it :slight_smile: