[Portaudio] Allow tweaking PA callback thread scheduler and priority

Markus Svilans msvilans at aeonyx.ca
Sat Mar 19 13:15:37 EDT 2016

Dear PortAudio authors,

Thank you for producing an excellent audio library.

Recently I was working on an embedded Linux project, with several 
threads at various SCHED_RR and SCHED_FIFO priorities. I found that the 
PortAudio stream was getting interrupted with overflows and underflows 
now and then, because PA callback thread was getting pre-empted by other 
threads. The default PortAudio real-time scheduling was being set to 
SCHED_FIFO at a priority of 1.

To work around the issue, I changed the PortAudio callback thread to use 
the SCHED_RR scheduler and the highest priority. Now the audio stream 
does not get interrupted. The attached patch shows what I did. It is 
based on code from PortAudio SVN rev 1919 

With the patch, you can control the callback thread scheduler and 
priority using two #defines:

I set the defaults to SCHED_RR and sched_get_priority_max(SCHED_RR), 

As a side not, if you want real-time scheduling for your PA callbacks, 
don't forget to activate real-time scheduling on your audio stream:

#include <pa_linux_alsa.h>
PaStream *stream;
// initialize audio stream etc. etc.
PaAlsa_EnableRealtimeScheduling(stream, 1);
// start audio stream

This patch hard-codes the scheduler options, but in the future people 
might find it useful to add these properties to the PaStream struct, so 
they can be tweaked at runtime and/or on an OS specific basis.

Thank you and best wishes,

-------------- next part --------------
From 514cd9e52f53ebc780aeade40b08368476d971f9 Mon Sep 17 00:00:00 2001
From: Markus Svilans <msvilans at aeonyx.ca>
Date: Fri, 18 Mar 2016 09:22:57 -0400
Subject: [PATCH 1/1] Allow controlling callback thread real-time scheduler
 and priority using #defines

 src/os/unix/pa_unix_util.c |   14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/src/os/unix/pa_unix_util.c b/src/os/unix/pa_unix_util.c
index 18f806c..6d509e4 100644
--- a/src/os/unix/pa_unix_util.c
+++ b/src/os/unix/pa_unix_util.c
@@ -242,16 +242,24 @@ PaError PaUnixThreading_Initialize()
     return paNoError;
+#if !defined(PA_RT_SCHED)
+#if !defined(PA_RT_PRIORITY)
+#define PA_RT_PRIORITY sched_get_priority_max(PA_RT_SCHED)
 static PaError BoostPriority( PaUnixThread* self )
     PaError result = paNoError;
     struct sched_param spm = { 0 };
-    /* Priority should only matter between contending FIFO threads? */
-    spm.sched_priority = 1;
+    spm.sched_priority = PA_RT_PRIORITY;
     assert( self );
-    if( pthread_setschedparam( self->thread, SCHED_FIFO, &spm ) != 0 )
+    if( pthread_setschedparam( self->thread, PA_RT_SCHED, &spm ) != 0 )
         PA_UNLESS( errno == EPERM, paInternalError );  /* Lack permission to raise priority */
         PA_DEBUG(( "Failed bumping priority\n" ));

More information about the Portaudio mailing list