aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c38
-rw-r--r--Alc/alsa.c6
-rw-r--r--Alc/dsound.c2
-rw-r--r--Alc/oss.c4
-rw-r--r--Alc/solaris.c2
-rw-r--r--OpenAL32/Include/alMain.h20
-rw-r--r--alsoftrc.sample9
7 files changed, 59 insertions, 22 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 9225f330..970b98c9 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -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, &param);
+ }
+ else
+ {
+ param.sched_priority = 0;
+ failed = !!pthread_setschedparam(pthread_self(), SCHED_OTHER, &param);
+ }
+#else
+ /* Real-time priority not available */
+ failed = !!level;
+#endif
+ if(failed)
+ AL_PRINT("Failed to set priority level for thread\n");
+}
+
+
/*
IsDevice
diff --git a/Alc/alsa.c b/Alc/alsa.c
index cfe80640..85092ceb 100644
--- a/Alc/alsa.c
+++ b/Alc/alsa.c
@@ -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);
diff --git a/Alc/oss.c b/Alc/oss.c
index 4a7a48be..94380fde 100644
--- a/Alc/oss.c
+++ b/Alc/oss.c
@@ -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, &param);
-#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