diff options
-rw-r--r-- | Alc/ALc.c | 38 | ||||
-rw-r--r-- | Alc/alsa.c | 6 | ||||
-rw-r--r-- | Alc/dsound.c | 2 | ||||
-rw-r--r-- | Alc/oss.c | 4 | ||||
-rw-r--r-- | Alc/solaris.c | 2 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 20 | ||||
-rw-r--r-- | alsoftrc.sample | 9 |
7 files changed, 59 insertions, 22 deletions
@@ -208,6 +208,9 @@ static tls_type LocalContext; // Context Error static ALCenum g_eLastContextError = ALC_NO_ERROR; +// Mixing Priority Level +ALint RTPrioLevel; + /////////////////////////////////////////////////////// @@ -253,6 +256,8 @@ static void alc_init(void) tls_create(&LocalContext); + RTPrioLevel = GetConfigValueInt(NULL, "rt-prio", 0); + devs = GetConfigValue(NULL, "drivers", ""); if(devs[0]) { @@ -424,6 +429,39 @@ DECL_APPEND_LIST_FUNC(AllDevice) DECL_APPEND_LIST_FUNC(CaptureDevice) +void EnableRTPrio(ALint level) +{ + ALboolean failed; + +#ifdef _WIN32 + if(level > 0) + failed = !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); + else + failed = !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); +#elif defined(HAVE_PTHREAD_SETSCHEDPARAM) + struct sched_param param; + + if(level > 0) + { + /* Use the minimum real-time priority possible for now (on Linux this + * should be 1 for SCHED_RR) */ + param.sched_priority = sched_get_priority_min(SCHED_RR); + failed = !!pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); + } + else + { + param.sched_priority = 0; + failed = !!pthread_setschedparam(pthread_self(), SCHED_OTHER, ¶m); + } +#else + /* Real-time priority not available */ + failed = !!level; +#endif + if(failed) + AL_PRINT("Failed to set priority level for thread\n"); +} + + /* IsDevice @@ -271,7 +271,7 @@ static ALuint ALSAProc(ALvoid *ptr) char *WritePtr; int err; - EnableRTPrio(); + EnableRTPrio(RTPrioLevel); while(!data->killNow) { @@ -345,7 +345,7 @@ static ALuint ALSANoMMapProc(ALvoid *ptr) snd_pcm_sframes_t avail; char *WritePtr; - EnableRTPrio(); + EnableRTPrio(RTPrioLevel); while(!data->killNow) { @@ -400,7 +400,7 @@ static ALuint ALSANoMMapCaptureProc(ALvoid *ptr) alsa_data *data = (alsa_data*)pDevice->ExtraData; snd_pcm_sframes_t avail; - EnableRTPrio(); + EnableRTPrio(RTPrioLevel); while(!data->killNow) { diff --git a/Alc/dsound.c b/Alc/dsound.c index 4a20b93e..e6294a43 100644 --- a/Alc/dsound.c +++ b/Alc/dsound.c @@ -134,7 +134,7 @@ static ALuint DSoundProc(ALvoid *ptr) DWORD avail; HRESULT err; - EnableRTPrio(); + EnableRTPrio(RTPrioLevel); memset(&DSBCaps, 0, sizeof(DSBCaps)); DSBCaps.dwSize = sizeof(DSBCaps); @@ -82,7 +82,7 @@ static ALuint OSSProc(ALvoid *ptr) ALint frameSize; ssize_t wrote; - EnableRTPrio(); + EnableRTPrio(RTPrioLevel); frameSize = aluChannelsFromFormat(pDevice->Format) * aluBytesFromFormat(pDevice->Format); @@ -124,7 +124,7 @@ static ALuint OSSCaptureProc(ALvoid *ptr) int frameSize; int amt; - EnableRTPrio(); + EnableRTPrio(RTPrioLevel); frameSize = aluBytesFromFormat(pDevice->Format); frameSize *= aluChannelsFromFormat(pDevice->Format); diff --git a/Alc/solaris.c b/Alc/solaris.c index 6cfaaa11..a6a0dda4 100644 --- a/Alc/solaris.c +++ b/Alc/solaris.c @@ -57,6 +57,8 @@ static ALuint SolarisProc(ALvoid *ptr) ALint frameSize; int wrote; + EnableRTPrio(RTPrioLevel); + frameSize = aluChannelsFromFormat(pDevice->Format) * aluBytesFromFormat(pDevice->Format); diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 0820b9dc..69bd9d5b 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -181,22 +181,6 @@ static __inline ALuint NextPowerOf2(ALuint value) return powerOf2; } -static __inline void EnableRTPrio() -{ -#ifdef _WIN32 - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); -#elif defined(HAVE_PTHREAD_SETSCHEDPARAM) - struct sched_param param; - - /* Use the minimum real-time priority possible for now (on Linux this - * should be 1 for SCHED_RR) */ - param.sched_priority = sched_get_priority_min(SCHED_RR); - pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); -#else - /* Real-time priority not available */ -#endif -} - typedef struct { ALCboolean (*OpenPlayback)(ALCdevice*, const ALCchar*); @@ -343,6 +327,8 @@ struct ALCcontext_struct ALCcontext *next; }; +extern ALint RTPrioLevel; + ALCvoid ReleaseALC(ALCvoid); void AppendDeviceList(const ALCchar *name); @@ -373,6 +359,8 @@ int GetConfigValueInt(const char *blockName, const char *keyName, int def); float GetConfigValueFloat(const char *blockName, const char *keyName, float def); int GetConfigValueBool(const char *blockName, const char *keyName, float def); +void EnableRTPrio(ALint level); + ALCboolean ALCAPIENTRY alcMakeCurrent(ALCcontext *context); ALCcontext* ALCAPIENTRY alcGetThreadContext(void); diff --git a/alsoftrc.sample b/alsoftrc.sample index b3882598..8efae414 100644 --- a/alsoftrc.sample +++ b/alsoftrc.sample @@ -52,6 +52,15 @@ # Sets the output frequency. #frequency = 44100 +## rt-prio: +# Sets real-time priority for the mixing thread. Not all drivers may use this +# (eg. PulseAudio) as they already control the priority of the mixing thread. +# 0 and negative values will disable it. Note that this may constitute a +# security risk since a real-time priority thread can indefinitely block +# normal-priority threads if it fails to wait. As such, the default is +# disabled. +#rt-prio = 0 + ## period_size: # Sets the update period size, in frames. This is the number of frames needed # for each mixing update. If the deprecated 'refresh' option is specified and |