[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 
(http://www.portaudio.com/archives/pa_stable_v19_20140130.tgz).

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

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

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,
Markus


-------------- 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)
+#define PA_RT_SCHED SCHED_RR
+#endif
+
+#if !defined(PA_RT_PRIORITY)
+#define PA_RT_PRIORITY sched_get_priority_max(PA_RT_SCHED)
+#endif
+
 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" ));
-- 
1.7.10.4


More information about the Portaudio mailing list