Add an option for real-time priority mixing

Default to disable for now, as a safety precaution
This commit is contained in:
Chris Robinson 2009-12-01 23:15:09 -08:00
parent 0e1e8503e0
commit 6cfc31777b
7 changed files with 59 additions and 22 deletions

View File

@ -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

View File

@ -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)
{

View File

@ -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);

View File

@ -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);

View File

@ -57,6 +57,8 @@ static ALuint SolarisProc(ALvoid *ptr)
ALint frameSize;
int wrote;
EnableRTPrio(RTPrioLevel);
frameSize = aluChannelsFromFormat(pDevice->Format) *
aluBytesFromFormat(pDevice->Format);

View File

@ -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);

View File

@ -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