In this tutorial, we will be discussing a Semaphore and its types ie. Binary, Mutex, Counting.
Later we will see each semaphore in detail with its pros and cons. Also, we will be looking into priority inversion and priority inheritance.

What is a Semaphore?

Semaphore is a technique for synchronizing two/more task competing for the same resources. When a task wants to use a resource, it requests for the semaphore and will be allocated if the semaphore is available. If the semaphore is not available then the requesting task will go to blocked state till the semaphore becomes free.

Consider a situation where there are two persons who want to share a bike. At one time only one person can use the bike. The one who has the bike key will get the chance to use it. And when this person gives the key to the 2nd person, then the 2nd person can use the bike.

Semaphore is just like this Key and the bike is the shared resource. Whenever a task wants access to the shared resource, it must acquire the semaphore first. The task should release the semaphore after it is done with the shared resource. Until this time all other tasks have to wait if they need access to shared resource as semaphore is not available. Even if the task trying to acquire the semaphore is of higher priority than the task acquiring the semaphore, it will be in the wait state until the semaphore is released by the lower priority task.

Types of Semaphores

There are 3-types of semaphores namely Binary, Counting and Mutex semaphore.

  • Binary Semaphore: Binary semaphore is used when there is only one shared resource.

Binary semaphore exists in two states ie.Acquired(Take), Released(Give). Binary semaphores have no ownership and can be released by any task or ISR regardless of who performed the last take operation. Because of this binary semaphores are often used to synchronize tasks with external events implemented as ISRs, for example waiting for a packet from a network or waiting for a button is pressed.

Because there is no ownership concept a binary semaphore object can be created to be either in the “taken” or “not taken” state initially.

Cons:

  1. Priority Inversion : HPT needs to wait for the LPT as LPT is holding the resource required for HPT. In between if MPT task comes then LPT will be in blocked state thereby delaying HPT.
  2. Does not support recursion : If a task tries to take the semaphore twice then it gets blocked and will not come out of state till someone releases that semaphore.
  3. No ownership : Anyone can release or delete the semaphore because of which the dependent tasks will always be in the blocked state.
  • Counnting Semaphore: To handle more than one shared resource of the same type, counting semaphore is used.
  • Mutex Semaphore: To avoid extended priority inversion, mutexes can be used.