The Semaphore structure is defined in the header file /include/linux/semaphore.h. The structure is shown below
- lock – spinlock that is to acquire the resource
- count – The count of the number of instances of the resource the semaphore provides access
- wait_list – a list of processes that are waiting to obtain the lock
The semaphore can be initialized statically or dynamically. They are via
- DEFINE_SEMAPHORE Macro (Statically assigned semaphore)
- sema_init function (dynamically assigned semaphore)
As was discussed earlier, if the count is set to 1, then the semaphore behaves as a binary semaphore and provides mutual exclusion. The DEFINE_SEMAPHORE Macro as seen above provides a count value of 1 and hence can initialize a binary semaphore. The sema_init function can be used to initialize a semaphore count value of greater than 1.
The below table provides a few of the semaphore APIs that are used in the Linux kernel.
void sema_init(struct semaphore *sem, int val) | Dynamically initialize a Semaphore |
int __must_check down_interruptible(struct semaphore *sem); | Acquire Semaphore, decrement count and set task to TASK_INTERRUPTIBLE state |
int __must_check down_killable(struct semaphore *sem); | Acquire Semaphore, decrement count and set task to TASK_KILLABLE state |
int __must_check down_trylock(struct semaphore *sem); | Try and acquire the Semaphore, if lock is unavailable – do not wait for lock to be acquired |
int __must_check down_timeout(struct semaphore *sem, long jiffies); | Try to acquire the Semaphore and exit if timeout expires |
void down(struct semaphore *sem); | Acquire a Semaphore |
void up(struct semaphore *sem); | Release a Semaphore |
Pingback: Semaphores in the Linux Kernel | Hitch Hiker's Guide to Learning