Assume that the following code is being executed by 10 threads.
pthread_mutex_lock(&lock)
Some trivial code
pthread_mutex_unlock(&lock)
For purpose of explanations lets say the threads are T1, T2, T3.....T10. My requirement is that as long as T1 or T2 or T3( i.e any of T1, T2 or T3) is waiting for acquiring a lock, the other threads i.t T4, T5, T6.....T10 should not be able to acquire the lock i.e T1, T2 and T3 should have precedence in acquiring the lock with respect to other threads.
I guess it could be done by increasing the priority of threads T1, T2 and T3
i.e here is the pseudo code
if this thread is T1 or T2 or T3
increase its priority
pthread_mutex_lock(&lock)
Some trivial code
pthread_mutex_unlock(&lock)
if this thread is T1 or T2 or T3 decrease it priority to normal
Please note that I want a solution that is works for Linux platform and should use pthreads. I don't really care about any other platform.
Also note that I don't really want to make these 3 threads as realtime, I want them to exhibit their defualt behaviour(scheduling and priority) except that in the above mentioned small piece of code I want them to always have precedence in acquiring lock.
I have read some man pages about scheduling policies and scheduling priorities in Linux but can't really make out :(
Will this work? Can you help me with the exact pthread API required to accomplish the above task?
Regards lali
Mutex lock will only be released by the thread who locked it. So this ensures that once a thread has locked a piece of code then no other thread can execute the same region until it is unlocked by the thread who locked it.
A recursive mutex can be locked repeatedly by the owner. The mutex does not become unlocked until the owner has called pthread_mutex_unlock() for each successful lock request that it has outstanding on the mutex. An errorcheck mutex checks for deadlock conditions that occur when a thread relocks an already held mutex.
The mutex object referenced by mutex shall be locked by calling pthread_mutex_lock(). If the mutex is already locked, the calling thread shall block until the mutex becomes available. This operation shall return with the mutex object referenced by mutex in the locked state with the calling thread as its owner.
The non-member function lock allows to lock more than one mutex object simultaneously, avoiding the potential deadlocks that can happen when multiple threads lock/unlock individual mutex objects in different orders.
Here's my implementation. Low priority threads use prio_lock_low()
and prio_unlock_low()
to lock and unlock, high priority threads use prio_lock_high()
and prio_unlock_high()
.
The design is quite simple. High priority threads are held at the critical section mutex ->cs_mutex
, low priority threads are held at the condition variable. The condition variable mutex is only held around updates to the shared variable and signalling of the condition variable.
#include <pthread.h>
typedef struct prio_lock {
pthread_cond_t cond;
pthread_mutex_t cv_mutex; /* Condition variable mutex */
pthread_mutex_t cs_mutex; /* Critical section mutex */
unsigned long high_waiters;
} prio_lock_t;
#define PRIO_LOCK_INITIALIZER { PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER }
void prio_lock_low(prio_lock_t *prio_lock)
{
pthread_mutex_lock(&prio_lock->cv_mutex);
while (prio_lock->high_waiters || pthread_mutex_trylock(&prio_lock->cs_mutex))
{
pthread_cond_wait(&prio_lock->cond, &prio_lock->cv_mutex);
}
pthread_mutex_unlock(&prio_lock->cv_mutex);
}
void prio_unlock_low(prio_lock_t *prio_lock)
{
pthread_mutex_unlock(&prio_lock->cs_mutex);
pthread_mutex_lock(&prio_lock->cv_mutex);
if (!prio_lock->high_waiters)
pthread_cond_signal(&prio_lock->cond);
pthread_mutex_unlock(&prio_lock->cv_mutex);
}
void prio_lock_high(prio_lock_t *prio_lock)
{
pthread_mutex_lock(&prio_lock->cv_mutex);
prio_lock->high_waiters++;
pthread_mutex_unlock(&prio_lock->cv_mutex);
pthread_mutex_lock(&prio_lock->cs_mutex);
}
void prio_unlock_high(prio_lock_t *prio_lock)
{
pthread_mutex_unlock(&prio_lock->cs_mutex);
pthread_mutex_lock(&prio_lock->cv_mutex);
prio_lock->high_waiters--;
if (!prio_lock->high_waiters)
pthread_cond_signal(&prio_lock->cond);
pthread_mutex_unlock(&prio_lock->cv_mutex);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With