Consider the following program (test.cc): #include <pthread.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #define C(c) if(int e = (c)) { errno = e; perror(#c); exit(EXIT_FAILURE); } int main() { pthread_mutexattr_t attr; pthread_mutex_t plock; C(pthread_mutexattr_init(&attr)); C(pthread_mutexattr_setprioceiling(&attr, 99)); C(pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_PROTECT)); C(pthread_mutex_init(&plock, &attr)); C(pthread_mutexattr_destroy(&attr)); if(int e = pthread_mutex_lock(&plock)) { errno = e; perror("1st pthread_mutex_lock"); if(int e = pthread_mutex_lock(&plock)) { errno = e; perror("2nd pthread_mutex_lock"); } else { printf("2nd pthread_mutex_lock succeeded\n"); } } else { printf("1st pthread_mutex_lock succeeded\n"); } } Compiled as: $ g++ --version g++ (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0 Copyright (C) 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ g++ -o test -O2 -W{all,extra,error} -pthread test.cc $ ldd test linux-vdso.so.1 (0x00007fffa69b2000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa4e445b000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa4e406a000) /lib64/ld-linux-x86-64.so.2 (0x00007fa4e487d000) $ /lib/x86_64-linux-gnu/libc.so.6 GNU C Library (Ubuntu GLIBC 2.27-3ubuntu1) stable release version 2.27. Copyright (C) 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Compiled by GNU CC version 7.3.0. libc ABIs: UNIQUE IFUNC For bug reporting instructions, please see: <https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>. Now let's run it: $ ./test 1st pthread_mutex_lock: Invalid argument 2nd pthread_mutex_lock succeeded $ sudo chrt --fifo 1 ./test 1st pthread_mutex_lock succeeded The question is: why does the 1st pthread_mutex_lock fails but the 2nd pthread_mutex_lock succeeds when the calling thread has wrong priority class for the priority ceiling?