Synchronization Mechanisms in the Linux Kernel: Mutex vs Semaphore

Synchronization Mechanisms in the Linux Kernel: Mutex vs Semaphore

Mutex

A mutex (short for mutual exclusion) is a synchronization primitive that allows multiple threads to take turns accessing a shared resource. Only one thread can hold the mutex at a time, and other threads requesting the mutex have to wait until it is released. Mutexes are commonly used when the shared resource is protected by a critical section that should only be accessed by one thread at a time.

Article content

As shows in above code snippet, a struct shared_data contains a counter variable and a mutex lock. The increment_counter() function increments the counter by acquiring the mutex lock using mutex_lock() and releasing it using mutex_unlock(). This ensures that only one thread can access the counter at a time, preventing concurrent updates.

Let's see the use of mutex in the kernel driver

kernel driver example ref

Article content

Let's look at the code snippet of driver which usage the mutex lock.

  1. need to initialize the mutex during probe.
  2. In the example of the ov5640_s_power() function, a mutex lock and unlock are used to ensure the proper powering on or off of the camera sensor. This operation may involve writing to the I2C registers, which could create issues if not synchronized properly. By using a mutex, we can guarantee that the necessary steps are performed correctly. Once the operation is completed, the mutex is unlocked to release the associated resources.

Semaphore

A semaphore is a synchronization primitive that allows a specified number of threads to access a shared resource simultaneously. It maintains a count that can be incremented or decremented. When a thread wants to access the shared resource, it tries to decrement the semaphore count. If the count is non-zero, the thread is allowed access; otherwise, it waits until the count becomes non-zero.

Article content

In this example, a struct shared_data contains a counter variable and a semaphore. The increment_counter() function increments the counter by acquiring the semaphore using down() and releasing it using up(). The semaphore ensures that a specified number of threads can access the counter simultaneously, preventing concurrent updates beyond the allowed limit.

Let's see the use of semaphore in the kernel driver

semaphore driver use ref

Article content


Let's look at the code snippet of driver which usage the semaphore locking mechanism

  1. need to initialize the semaphore during probe. here they used 2 semaphore param_lock and busy_lock.
  2. down(&cam->param_lock): This operation attempts to decrement the semaphore count. If the count is greater than zero, the operation succeeds, and the thread can proceed. If the count is zero (indicating that the semaphore is currently locked by another thread), the down() operation will block the current thread, putting it into a waiting state until the semaphore is released by an up() operation from another thread.
  3. up(&cam->param_lock): This operation increments the semaphore count, releasing the semaphore and allowing other waiting threads to proceed.

Mutex Vs Semaphore
Article content

In conclusion, mutexes and semaphores are both important synchronization mechanisms in the Linux kernel, each with its own advantages and disadvantages. The choice between them depends on the specific requirements and characteristics of the problem at hand. I hope this will help you to understand these concepts about Mutex & Semaphore

Good write up Ritesh, you can improve it by adding more usecases e.g. 1 . Handling in Interrrupt context 2. Semaphore usage in multiple context.

To view or add a comment, sign in

More articles by Ritesh Kumar

Others also viewed

Explore content categories