aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-11-21 09:07:02 -0800
committerChris Robinson <[email protected]>2018-11-21 09:07:02 -0800
commit9f2a77f78801da760df582900ec862fff6438a09 (patch)
tree5a8bdbbf8519aaca1bb92c836b165fad64b60b39
parent8f43f737ba5f0ed32a37498f6787c34257a3f796 (diff)
Use RAII when handling the mixer's FPU state
-rw-r--r--Alc/alc.cpp4
-rw-r--r--Alc/alu.cpp3
-rw-r--r--Alc/converter.cpp6
-rw-r--r--Alc/fpu_modes.h44
-rw-r--r--Alc/helpers.cpp25
-rw-r--r--OpenAL32/alAuxEffectSlot.cpp26
6 files changed, 47 insertions, 61 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp
index 5c46b950..d9fa549a 100644
--- a/Alc/alc.cpp
+++ b/Alc/alc.cpp
@@ -2241,7 +2241,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
* allocated with the appropriate size.
*/
update_failed = AL_FALSE;
- START_MIXER_MODE();
+ FPUCtl mixer_mode{};
context = device->ContextList.load();
while(context)
{
@@ -2354,7 +2354,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
context = context->next.load(std::memory_order_relaxed);
}
- END_MIXER_MODE();
+ mixer_mode.leave();
if(update_failed)
return ALC_INVALID_DEVICE;
diff --git a/Alc/alu.cpp b/Alc/alu.cpp
index faa011a2..b3ffd24b 100644
--- a/Alc/alu.cpp
+++ b/Alc/alu.cpp
@@ -1697,7 +1697,7 @@ void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples)
ALCcontext *ctx;
ALsizei i, c;
- START_MIXER_MODE();
+ FPUCtl mixer_mode{};
for(SamplesDone = 0;SamplesDone < NumSamples;)
{
SamplesToDo = mini(NumSamples-SamplesDone, BUFFERSIZE);
@@ -1815,7 +1815,6 @@ void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples)
SamplesDone += SamplesToDo;
}
- END_MIXER_MODE();
}
diff --git a/Alc/converter.cpp b/Alc/converter.cpp
index d64bc328..72015db0 100644
--- a/Alc/converter.cpp
+++ b/Alc/converter.cpp
@@ -154,7 +154,7 @@ SampleConverter *CreateSampleConverter(enum DevFmtType srcType, enum DevFmtType
converter->mFracOffset = 0;
/* Have to set the mixer FPU mode since that's what the resampler code expects. */
- START_MIXER_MODE();
+ FPUCtl mixer_mode{};
step = (ALsizei)mind(((ALdouble)srcRate/dstRate*FRACTIONONE) + 0.5,
MAX_PITCH * FRACTIONONE);
converter->mIncrement = maxi(step, 1);
@@ -166,7 +166,6 @@ SampleConverter *CreateSampleConverter(enum DevFmtType srcType, enum DevFmtType
BsincPrepare(converter->mIncrement, &converter->mState.bsinc, &bsinc12);
converter->mResample = SelectResampler(BSinc12Resampler);
}
- END_MIXER_MODE();
return converter;
}
@@ -227,7 +226,7 @@ ALsizei SampleConverterInput(SampleConverter *converter, const ALvoid **src, ALs
const ALsizei increment = converter->mIncrement;
ALsizei pos = 0;
- START_MIXER_MODE();
+ FPUCtl mixer_mode{};
while(pos < dstframes && *srcframes > 0)
{
ALfloat *RESTRICT SrcData = converter->mSrcSamples;
@@ -339,7 +338,6 @@ ALsizei SampleConverterInput(SampleConverter *converter, const ALvoid **src, ALs
dst = (ALbyte*)dst + DstFrameSize*DstSize;
pos += DstSize;
}
- END_MIXER_MODE();
return pos;
}
diff --git a/Alc/fpu_modes.h b/Alc/fpu_modes.h
index e8858ad9..1afd6618 100644
--- a/Alc/fpu_modes.h
+++ b/Alc/fpu_modes.h
@@ -1,41 +1,25 @@
#ifndef FPU_MODES_H
#define FPU_MODES_H
-#ifdef HAVE_FENV_H
-#include <fenv.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct FPUCtl {
+class FPUCtl {
#if defined(__GNUC__) && defined(HAVE_SSE)
- unsigned int sse_state;
+ unsigned int sse_state{};
#elif defined(HAVE___CONTROL87_2)
- unsigned int state;
- unsigned int sse_state;
+ unsigned int state{};
+ unsigned int sse_state{};
#elif defined(HAVE__CONTROLFP)
- unsigned int state;
+ unsigned int state{};
#endif
-} FPUCtl;
-void SetMixerFPUMode(FPUCtl *ctl);
-void RestoreFPUMode(const FPUCtl *ctl);
+ bool in_mode{};
-#ifdef __GNUC__
-/* Use an alternate macro set with GCC to avoid accidental continue or break
- * statements within the mixer mode.
- */
-#define START_MIXER_MODE() __extension__({ FPUCtl _oldMode; SetMixerFPUMode(&_oldMode)
-#define END_MIXER_MODE() RestoreFPUMode(&_oldMode); })
-#else
-#define START_MIXER_MODE() do { FPUCtl _oldMode; SetMixerFPUMode(&_oldMode)
-#define END_MIXER_MODE() RestoreFPUMode(&_oldMode); } while(0)
-#endif
-#define LEAVE_MIXER_MODE() RestoreFPUMode(&_oldMode)
+public:
+ FPUCtl() noexcept;
+ ~FPUCtl() { leave(); }
-#ifdef __cplusplus
-} // extern "C"
-#endif
+ FPUCtl(const FPUCtl&) = delete;
+ FPUCtl& operator=(const FPUCtl&) = delete;
+
+ void leave() noexcept;
+};
#endif /* FPU_MODES_H */
diff --git a/Alc/helpers.cpp b/Alc/helpers.cpp
index a78e3d83..658c7d09 100644
--- a/Alc/helpers.cpp
+++ b/Alc/helpers.cpp
@@ -260,13 +260,13 @@ void FillCPUCaps(int capfilter)
}
-void SetMixerFPUMode(FPUCtl *ctl)
+FPUCtl::FPUCtl() noexcept
{
#if defined(__GNUC__) && defined(HAVE_SSE)
if((CPUCapFlags&CPU_CAP_SSE))
{
- __asm__ __volatile__("stmxcsr %0" : "=m" (*&ctl->sse_state));
- unsigned int sseState = ctl->sse_state;
+ __asm__ __volatile__("stmxcsr %0" : "=m" (*&this->sse_state));
+ unsigned int sseState = this->sse_state;
sseState |= 0x8000; /* set flush-to-zero */
if((CPUCapFlags&CPU_CAP_SSE2))
sseState |= 0x0040; /* set denormals-are-zero */
@@ -275,32 +275,37 @@ void SetMixerFPUMode(FPUCtl *ctl)
#elif defined(HAVE___CONTROL87_2)
- __control87_2(0, 0, &ctl->state, &ctl->sse_state);
+ __control87_2(0, 0, &this->state, &this->sse_state);
_control87(_DN_FLUSH, _MCW_DN);
#elif defined(HAVE__CONTROLFP)
- ctl->state = _controlfp(0, 0);
+ this->state = _controlfp(0, 0);
_controlfp(_DN_FLUSH, _MCW_DN);
#endif
+
+ this->in_mode = true;
}
-void RestoreFPUMode(const FPUCtl *ctl)
+void FPUCtl::leave() noexcept
{
+ if(!this->in_mode) return;
+
#if defined(__GNUC__) && defined(HAVE_SSE)
if((CPUCapFlags&CPU_CAP_SSE))
- __asm__ __volatile__("ldmxcsr %0" : : "m" (*&ctl->sse_state));
+ __asm__ __volatile__("ldmxcsr %0" : : "m" (*&this->sse_state));
#elif defined(HAVE___CONTROL87_2)
unsigned int mode;
- __control87_2(ctl->state, _MCW_DN, &mode, nullptr);
- __control87_2(ctl->sse_state, _MCW_DN, nullptr, &mode);
+ __control87_2(this->state, _MCW_DN, &mode, nullptr);
+ __control87_2(this->sse_state, _MCW_DN, nullptr, &mode);
#elif defined(HAVE__CONTROLFP)
- _controlfp(ctl->state, _MCW_DN);
+ _controlfp(this->state, _MCW_DN);
#endif
+ this->in_mode = false;
}
diff --git a/OpenAL32/alAuxEffectSlot.cpp b/OpenAL32/alAuxEffectSlot.cpp
index df2c2a43..60c44f49 100644
--- a/OpenAL32/alAuxEffectSlot.cpp
+++ b/OpenAL32/alAuxEffectSlot.cpp
@@ -514,19 +514,19 @@ ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect
EffectState *State{factory->create()};
if(!State) return AL_OUT_OF_MEMORY;
- START_MIXER_MODE(); {
- ALCdevice *Device{Context->Device};
- std::unique_lock<almtx_t> backlock{Device->BackendLock};
- State->mOutBuffer = Device->Dry.Buffer;
- State->mOutChannels = Device->Dry.NumChannels;
- if(State->deviceUpdate(Device) == AL_FALSE)
- {
- backlock.unlock();
- LEAVE_MIXER_MODE();
- State->DecRef();
- return AL_OUT_OF_MEMORY;
- }
- } END_MIXER_MODE();
+ FPUCtl mixer_mode{};
+ ALCdevice *Device{Context->Device};
+ std::unique_lock<almtx_t> backlock{Device->BackendLock};
+ State->mOutBuffer = Device->Dry.Buffer;
+ State->mOutChannels = Device->Dry.NumChannels;
+ if(State->deviceUpdate(Device) == AL_FALSE)
+ {
+ backlock.unlock();
+ mixer_mode.leave();
+ State->DecRef();
+ return AL_OUT_OF_MEMORY;
+ }
+ mixer_mode.leave();
if(!effect)
{