Reputation: 119
Edit: I'm attaching a snippet, I've initialized attr, and all calls were good.
I've been trying to use a mutex with PRIO_PROTECT, but first call returns EINVAL, while second call returns zero\success. here's what I've done:
pthread_mutexattr_setprioceiling(&attr, 99);
pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_PROTECT);
pthread_mutex_init(&plock, &attr);
pthread_mutexattr_destroy(&attr);
ret = pthread_mutex_lock(&plock); //now ret == EINVAL
ret = pthread_mutex_lock(&plock); // ret == 0
I understand that EINVAL means that the caller priority is higher than the ceiling, so I have 2 questions:
why does it work on the second try?
How to lower the thread's priority to the ceiling? or rather, set the ceiling to the thread's priority?
Upvotes: 1
Views: 186
Reputation: 16540
Are you trying to bump the current executing code priority or simply protect some data.
If simply trying to protect some data...
pthread_mutex_t myMutex = PTHREAD_MUTEX_INITIALIZER;
then when wanting to use the mutex:
pthread_mutex_lock( &myMutex );
... // manipulate the 'critical' data
Then when ready to allow another thread to access that same data.
... // finished manipulation of the 'critical' data
pthread_mutex_unlock( &myMutex );
Note: there are other values for the initialization, but the above macro value is the most common.
Upvotes: 0
Reputation: 136515
A call to pthread_mutexattr_init
is missing.
PTHREAD_PRIO_PROTECT
means:
When a thread owns one or more non-robust mutexes initialized with the PTHREAD_PRIO_PROTECT protocol, it shall execute at the higher of its priority or the highest of the priority ceilings of all the non-robust mutexes owned by this thread and initialized with this attribute, regardless of whether other threads are blocked on any of these non-robust mutexes or not.
Which means that pthread_mutex_lock
sets the priority of the current thread to max(current_priority, prioceiling)
. Your prioceiling
is 99 and such a priority requires a thread with real-time scheduling class (FIFO or round-robin).
In fact, any priority for pthread_mutexattr_setprioceiling
requires a real-time scheduling class:
The values of
prioceiling
are within the maximum range of priorities defined bySCHED_FIFO
.
This is because the functions you'd like to use belong to POSIX realtime extensions and the default scheduling class SCHED_OTHER
is there for:
This policy is defined to allow strictly conforming applications to be able to indicate in a portable manner that they no longer need a realtime scheduling policy.
If you run your application with sudo chrt --fifo 1 <app>
it assigns your process FIFO scheduling class of priority 1 which makes it succeed in locking the mutex on the first call.
Regarding why the 2nd call succeeds when the 1st one fails, that seems to be undocumented behaviour, if I am not mistaken, and is probably a bug in glibc.
Upvotes: 3