#41 xSemaphoreWait

open
nobody
4
2010-09-23
2010-07-29
Anonymous
No

I would like to have xSemaphoreWait in semphr.h included and documented in API.
I use this for task synchronization in case of having more than two tasks.

#define xSemaphoreWait( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdTRUE )

Discussion

  • Richard Damon
    Richard Damon
    2010-07-29

    Waiting on a Semaphore and not acquiring it is almost always a mistake. If two tasks are waiting on a semaphore and one task give it, then your proposed function will NOT guarantee that this task will be woken up also (just as a QueuePeek will not guarantee that the peeking task will see all items put on the queue.

    The best way to do this is for the giver to give two semaphores, and each tasks waits on its own. If the giver can't be modified, then have the higher priority taker wait on the semaphore that the giver gives, and it can then give a different semaphore for the lower priority to be taking.

    If you can not modify both receivers, making this operation reliable is very hard. If you are adding a lower priority task, it just won't work, when the higher priority task's take is processed, it will no longer be available for the lower one to peek,. If you are adding a higher priority task, you will need to make sure that after your task is notified of the semaphore being signaled, that before you test it again, that the lower priority task has taken the semaphore, or you will process a second time. If you can do this, then rather than doing your wait/peek, you can just take the semaphore and give it again (for the lower priority task).

     
  • Richard
    Richard
    2010-09-23

    What is the difference between this and the existing xSemaphoreTake() function?

     
  • Richard
    Richard
    2010-09-23

    • priority: 5 --> 4
     
  • Richard Damon
    Richard Damon
    2010-09-23

    I think what he wants is a variation that waits for the semaphore, but doesn't take it when there, sort of a "peek" function. I think the plan is to have one task "wait" and a second task "take" so when it is given both start back up. I think that this has several design issues with reliability (it requires that both waiting tasks actually get to their requests before the give, the waiting task (as opposed to the taking task) must have a higher priority, and the waiting task must not finish it's processing and wait again before the taking task gets time (and remember it has a higher priority, so it needs to have to dismiss on something else to pass the time down to the taking task). You can the proposal by doing a take/give in the higher priority task (which makes the issues more obvious), and the better solution is to give each of the tasks its own semaphore, and give both of them.

     
  • Bill Howell
    Bill Howell
    2010-11-17

    It may be that what he/she wants is more like an event than a semaphore: the difference being that an event is not 'taken' in the same sense as a semaphore, but provides a block/unblock rendezvous kind of semantics:

    The operations on an event are Set and Clear, and the states are Asserted and Deasserted.
    Set causes the event state to be Asserted.
    Clear causes the event state to be Deasserted.

    On a context calling for an event Wait decision:
    If the event is Asserted, then the calling context proceeds.
    If the event is Deasserted, then the calling context blocks until the event is Asserted.

    When the event changes state due to an event Set call, all blocked threads are made ready.

    I've seen this primitive in a couple of other OS's, I will admit to not being very fond of it, but think that this is what the requester may have been thinking of.