[Vm-dev] linux thread priorities

Eliot Miranda eliot.miranda at gmail.com
Thu Feb 4 02:01:00 UTC 2010


 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
pthread_cond_wait.  But...

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:

NAME
       sched_yield - yield the processor

SYNOPSIS
       #include <sched.h>

       int sched_yield(void);

DESCRIPTION
       A  process can relinquish the processor voluntarily without blocking
by
       calling sched_yield().  The process will then be moved to  the  end
 of
       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
prior-
       ity list at that time, this process will continue to run after  a
 call
       to sched_yield().

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
non-superuser process?
- is there an implementation of pthread_yield's intended functionality I'm
missing that will yield to other threads within the process?


best
Eliot

(*) 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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20100203/5e785c03/attachment.htm


More information about the Vm-dev mailing list