5.5.5 Priority-aware mutexes
#if defined (_POSIX_THREAD_PRIO_PROTECT)
|| defined (_POSIX_THREAD_PRIO_INHERIT)
int pthread_mutexattr_getprotocol (
const pthread_mutexattr_t *attr, int *protocol);
int pthread_mutexattr_setprotocol (
pthread_mutexattr_t *attr, int protocol);
#endif
#ifdef _POSIX_THREAD_PRIO_PROTECT
int pthread_mutexattr_getprioceiling (
const pthread_attr_t *attr, int *prioceiling);
int pthread_mutexattr_setprioceiling (
pthread_mutexattr_t *attr, int prioceiling);
int pthread_mutex_getprioceiling (
const pthread_mutex_t *mutex, int *prioceiling);
int pthread_mutex_setprioceiling (
pthread_mutex_t *mutex,
int prioceiling, int *old_ceiling);
#endif
Pthreads provides several special mutex attributes that can help to avoid priority inversion deadlocks. Locking, or waiting for, a mutex with one of these attributes may change the priority of the thread — or the priority of other threads— to ensure that the thread that owns the mutex cannot be preempted by another thread that needs to lock the same mutex.
These mutex attributes may not be supported by your implementation of Pthreads, because they are optional features. If your code needs to function with or without these options, you can conditionally compile references based on the feature test macros _POSIX_THREAD_PRIO_PROTECT or _POSIX_THREAD_PRIO_ INHERIT, defined in <unistd.h>, or you can call sysconf during program execution to check for SC_THREAD_PRIO_PROTECT or SC_THREAD_PRIO_INHERIT.
Once you've created a mutex using one of these attributes, you can lock and unlock the mutex exactly like any other mutex. As a consequence, you can easily convert any mutex you create by changing the code that initializes the mutex. (You must call pthread_mutex_init, however, because you cannot statically initialize a mutex with nondefault attributes.)
'Priority ceiling' protocol means that while a thread owns the mutex, it runs at the specified priority.
If your system defines _POSIX_THREAD_PRIO_PROTECT then it supports the
You set the
'Priority inheritance' means that when a thread waits on a mutex owned by a lower-priority thread,the priority of the owner is increased to that of the waiter.
If your system defines _POSIX_THREAD_PRIO_INHERIT then it supports the
If your system does not define either _POSIX_THREAD_PRIO_PROTECT or _POSIX_ THREAD_PRIO_INHERIT then the
5.5.5.1 Priority ceiling mutexes
The simplest of the two types of 'priority aware' mutexes is the
FIGURE 5.3
priority automatically raised to that value, which will allow it to finish with the mutex before it can be preempted by any other thread that might try to lock the mutex. You can also examine or modify the priority ceiling of a mutex that was created with the priority ceiling
A priority ceiling mutex is not useful within a library that can be called by threads you don't control. If any thread that is running at a priority above the ceiling locks the priority ceiling mutex, the protocol is broken. This doesn't necessarily guarantee a priority inversion, but it removes all protection against priority inversion. Since the priority ceiling protocol adds overhead to each mutex operation compared to a normal 'unprotected' mutex, you may have wasted processor time accomplishing nothing.
Priority ceiling is perfect for an embedded realtime application where the developers control all synchronization within the system. The priority ceiling can be safely determined when the code is designed, and you can avoid priority inversion with a relatively small cost in performance compared to more general solutions. Of course it is always most efficient to avoid priority inversion, either by avoiding priority scheduling or by using any given mutex only within threads of equal priority. Equally, of course, these alternatives rarely prove practical when you need them most.
You can use priority ceiling within almost any main program, even when you don't control the code in libraries you use. That's because while it is common for threads that call into library functions to lock library mutexes, it is not common for threads created by a library to call into application code and lock application mutexes. If you use a library that has 'callbacks' into your code, you must either ensure that those callbacks (and any functions they call) don't use the priority ceiling mutexes or that no thread in which the callback might be invoked will run at a priority above the ceiling priority of the mutex.
5.5.5.2 Priority inheritance mutexes
The other Pthreads mutex protocol is