Delete a task that waits for a binary semaphore

apica wrote on Monday, January 23, 2017:


I’m developing a middle layer between a peripheral an upper layers, and this middle layer has a binary semaphore.

The upper layers (threads) call the “Request” function of the middle layer, this takes the binary semaphore (xSemaphoreTake) to allow only one access to the peripheral at a time. Once the use of the peripheral is finished, the upper layer executes the “Release” function of the middle layer that releases the semaphore.

Now suppose the case that the semaphore is taken, and other upper layer (thread) executes the Request function. This will lead the thread to be waiting for the semaphore. If this thread is externally deleted, will the semaphore keep correct values? Is it safe to do?

Thank you

heinbali01 wrote on Monday, January 23, 2017:

I hope I understand your question:

When a task is being killed, the OS won’t know which semaphores were taken by the task.
I my opinion, it is more transparent to let a task kill itself. So if you want to kill a task, send it a message or set some flag to which it will respond. The task will know perfectly which resources it has claimed and what to do to terminate properly.

apica wrote on Monday, January 23, 2017:

Thank you Hein.

Yes, it would be easier if the task terminates itself and releases all the resources but I’m not sure if it is compatible with the low power. The xSemaphoreTake it was supposed to be blocked “forever” until the resource became available.

From your reply, I guess you are saying to avoid the “forever” semaphore and check from time to time a flag (or something else) to know if it has to terminate itself. Is that right?

Thank you

rtel wrote on Monday, January 23, 2017:

Are you asking what happens if the middle layer task gets deleted while
it has the semaphore, or what happens if a higher level task that is
blocked waiting for the semaphore gets deleted? If you are just talking
about the latter case, where a task attempts to take a semaphore,
blocks, then gets deleted before it unblocks, then nothing happens -
everything will be fine. The task will get deleted and removed from the
list of tasks waiting for the semaphore. This holds for binary
semaphores but not necessarily other types of semaphore.

richard_damon wrote on Tuesday, January 24, 2017:

I generally find that I don’t need to delete/recreate tasks, and that people doing this tend to be thinking much more of a unix type model with full processes, and not a micro-kernal with tasks (which are much more like threads on bigger machines). The key thing is that if you are going to delete a task, you are almost certainly going to also be recreating the task later, and without a lot of careful analysis, you need to be prepared for the create task to fail. The major way to be sure that the create will succeed (other than not deleting in the first place so you don’t need to recreate) is to have a lot of memory, but then there isn’t much need to delete the task in the first place.

Because tasks are NOT full blown processes of the unix ilk, you need to take a lot of care to be sure the task is in a proper state before deleting it (so you don’t lose resources), which tends to make it simplest that if you do delete tasks, it is them self-deleting, otherwise it is very hard to avoid race conditions.

apica wrote on Tuesday, January 24, 2017:

Yes, it was the second case (isn’t easy to explain).

Thank you!

apica wrote on Tuesday, January 24, 2017:

Hi Richard, thank you for your reply.

I understand your aproach. The main goal to delete / suspend / block a task is to enter in a low power mode. When the system decides to stop the device, it has to tell to the modules to stop working.

If a “release” function is executed from a upper layer, this function needs to stop the thread somehow and all its used resources (semaphores, queues, perihperals, …).

So, to set a bigger scope to thre problem:
How would you deal with low power while using freeRTOS based systems?

Thank you very much.

richard_damon wrote on Tuesday, January 24, 2017:

A task that is block indefinately on a semaphore or queue will not prevent the system from entering low power mode (the key is indefinately or at least for a long time), This generally SHOULD be the normal state for any task that doesn’t have something immediately to do anyway.

rtel wrote on Tuesday, January 24, 2017:

A task that is block indefinately on a semaphore or queue will not
prevent the system from entering low power mode

More so - that is exactly when the system WILL AUTOMATICALLY go into low
power, if configUSE_TICKLESS_IDLE is set to 1 (on ports that implement it).