From 9f2a77f78801da760df582900ec862fff6438a09 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 21 Nov 2018 09:07:02 -0800 Subject: Use RAII when handling the mixer's FPU state --- Alc/alc.cpp | 4 ++-- Alc/alu.cpp | 3 +-- Alc/converter.cpp | 6 ++---- Alc/fpu_modes.h | 44 ++++++++++++++------------------------------ Alc/helpers.cpp | 25 +++++++++++++++---------- OpenAL32/alAuxEffectSlot.cpp | 26 +++++++++++++------------- 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 -#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 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 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) { -- cgit v1.2.3