Delete task holding a mutex. Is it released?

alejandro79 wrote on Thursday, May 26, 2011:

Hi, one question.
Suppose I´m writing a task supervisor, and it discovers a problem with a task holding a mutex, or a MutexTake timesout, then i´d need the mutex released and the task holding it doesn’t do it.
If I vTaskDelete(mutexHolder); does the mutex get released?

And in a similar case, suppose I decide to suspend a task for the time being, and part of the task involves taking a mutex:
- Does the suspend cause the mutex to be released?
- Can I check with the task to see if the mutex is taken before I suspend (or delete) it? Or do I have to add my own flag?

Regards,
Alex

sven-de wrote on Thursday, May 26, 2011:

That’s an interesting question making me interested about one of the wise men replying.

The scheduler obviously has some knowledge about the current location of a mutex otherwise priority inheritance couldn’t be possible. Therefore it would be able to react on deleting this task.
But I don’t think there’s a perfect reaction to this situation: Imagine a task controlling some resource (shared memory) that allows other tasks access to that resource. The resource is useless without that task (writing the memory content to some interface). Freeing the mutex when that task isn’t able to give it back on it’s own wouldn’t be what you want.

Allowing your supervisor to take the mutex by force, (deleting and recreating the culprit) the releasing it could be an option.

On that note I wonder why there aren’t any API-functions to delete semaphores/mutexes as there are for queues…

edwards3 wrote on Thursday, May 26, 2011:

Suppose I´m writing a task supervisor, and it discovers a problem with a task holding a mutex, or a MutexTake timesout,

Would the easiest thing not to be to re-write the task so it does not contain that bug?

then i´d need the mutex released and the task holding it doesn’t do it.
If I vTaskDelete(mutexHolder); does the mutex get released?

No, it will not release the semaphore. It will remove the task being deleted from any block list if the task is waiting for a semaphore, but that is all. If the supervisor task can detect that there is a problem with the sempahore then it can release the semaphore before deleting the task. Probably best to do it that way round, although it would also probably work the other way around too (delete the task then release the semaphore).

And in a similar case, suppose I decide to suspend a task for the time being, and part of the task involves taking a mutex:
- Does the suspend cause the mutex to be released?

Of course not, how could that be a logical thing to do?  If it held a semaphore when it was suspended, when it was unsuspended it must also hold the semaphore, otherwise you will get into all sorts of problems if the semaphore is used for mutual exclusion. The task will not know when it is being suspended and unsuspended, or that that had happened, so won’t know it no longer has the semaphore. I don’t think there is a way for the task doing the unsuspending to give the semaphore back to the task being unsuspended. A semaphore can only be taken by a task, not passed to another task.

- Can I check with the task to see if the mutex is taken before I suspend (or delete) it? Or do I have to add my own flag?

I don’t think there is an easy way of checking, although you can add in a mechanism to the semaphore itself to see which task holds it. I think that information is held in the semaphore anyway (it is in a mutex semaphore I think) so you could add a simple query function. Alternatively, have the task set a flag as it takes the semaphore, then just check the flag.

rtel wrote on Thursday, May 26, 2011:

If you want a task A to suspend task B, but are worried that task B might be a mutex holder, then have task A attempt to take the mutex first. When task A holds the mutex it knows task B cannot also be holding it and can then safely suspend task B before just releasing the semaphore again.

In this scheme, if task A is the highest priority task then it will be guaranteed to be the next task to successfully obtain the semaphore, even if other tasks are already waiting on the same semaphore.

Regards.

rtel wrote on Thursday, May 26, 2011:

On that note I wonder why there aren’t any API-functions to delete semaphores/mutexes as there are for queues…

I missed that point in my first reply.

There is actually an API function to delete semaphores and mutexes, but maybe it is not obvious (I admit), and should be made so.  All types of semaphore (including mutexes) are implemented on top of the queue mechanism, and therefore all types of semaphore can be deleted using the vQueueDelete() API function.  You might have to cast the xSemaphoreHandle to an xQueueHandle to prevent a compiler warning, depending on the compiler, but it is safe to do.

Regards.

alejandro79 wrote on Thursday, May 26, 2011:

“No, it will not release the semaphore. It will remove the task being deleted from any block list if the task is waiting for a semaphore, but that is all. If the supervisor task can detect that there is a problem with the sempahore then it can release the semaphore before deleting the task. Probably best to do it that way round, although it would also probably work the other way around too (delete the task then release the semaphore).”

If I understand correctly, any task can give the mutex semaphore any other task is holding? A sort of “stealing” the mutex? There is no provision to detect that the task giving a mutex is actually the task holding it?
That would make a supervisor very easy to implement.

Regards,
Alex

rtel wrote on Thursday, May 26, 2011:

If I understand correctly, any task can give the mutex semaphore any other task is holding? A sort of “stealing” the mutex? There is no provision to detect that the task giving a mutex is actually the task holding it?
That would make a supervisor very easy to implement.

Be careful there.  I think, if it is a binary semaphore then anything can ‘give’ it, even if they don’t hold it, the same is, I think true for counting semaphores but would have to check.  If it is a mutex type semaphore, you definitely cannot give it without first holding it.  Recursive mutexes also cannot be given without first being held.

Regards.

alejandro79 wrote on Friday, May 27, 2011:

So if a task holding a mutex goes AWOL there´s nothing else to do but reset the whole thing?

davedoors wrote on Saturday, May 28, 2011:

I don’t think there is anything in FreeRTOS that would make a task go AWOL that I know of, so if one does it would be likely that the application was to blame. In which case, relying on an RTOS mechanism being available to correct the application is always going to be a bad idea. The problem will just keep happening and the application will not be running correctly. If you detect a task going AWOL I would recommend debugging your application as a first step.

alejandro79 wrote on Saturday, May 28, 2011:

Thanks to all for your replies.
Of course, debugging is always the first step, but there are situations (like temporary hardware failure) that can´t be debugged, just noted.

Regards,
Alex