I've been trying to get our sound framework going on linux and have got
stuck. I wondered whether anyone has any experience getting round this
problem on linux. It is complicated so excuse the lengthy explanation.
Our sound processing depends on a high-prirority thread running for a short
time every 20 milliseconds to push data through the sound processing paths
(microphone recording, OpenAL for spatialization, and so on). On linux this
approach is not immediately applicable because (*)
a) linux's pthreads implementation does not allow non-superuser programs to
create threads with other than the SCHED_OTHER scheduler, and
b) linux's pthreads implementation does not support different priorities for
the SCHED_OTHER scheduler
and so it is not possible for a non-superuser program to create a thread
that runs at a higher priority than any other thread in the process.
The approach I've explored so far has been to replace the high-pririty
thread with an interval timer, where a timer interrupt is delivered via a
signal handler. This approach won't work because it can very easily
deadlock. For example there are non-reentrant locks in functions such as
tz_convert (used within both localtime and localtime_r) such that if the
signal is delivered during a call to localtime, any nested call to
localtime, as is made by our logging code, will deadlock. I can avoid
deadlock in code under our own control, but not in platform functions such
as localtime upon which we depend.
Another approach would be (should be!) to still use two threads (which are
unfortunately of the same priority because of the above thread priority
restriction) but to cause the main VM thread to yield to the sound
processing thread. In this approach the timer interrupt would signal a
posix semaphore (via pthread_cond_signal) and then call pthread_yield. The
sound processing thread would loop blocking on the semaphore via
On contemporary linux (including CERN's distro) pthread_yield is implemented
as a straight call of the sched_yield(2) system call which does not yield to
other threads within the process, but to other processes within the
process's static priority. I quote:
sched_yield - yield the processor
A process can relinquish the processor voluntarily without blocking
calling sched_yield(). The process will then be moved to the end
the queue for its static priority and a new process gets to run.
Note: If the current process is the only process in the highest
ity list at that time, this process will continue to run after a
So, although I have yet to confirm this, it looks like pthread_yield will
not yield to the other thread. [I have confirmed that pthread_yield is a
direct call of sched_yield(2) however]. The manual page could be incorrect,
but my understanding is that on linux pthreads are a user-space
implementation and therefore there isn't any way that a call to sched_yield
is going to yield to another thread.
So my questions are
- is there any way I'm missing to create different priority threads in a
- is there an implementation of pthread_yield's intended functionality I'm
missing that will yield to other threads within the process?
(*) see sched_setscheduler(2) and in particular that RLIMIT_RTPRIO for
non-superuser programs is a maximum of 0, so one can't change the static
priority of a non-superuser program either.