diff options
| author | Moncef Mechri <moncef.mechri@gmail.com> | 2015-07-07 15:30:27 +0200 |
|---|---|---|
| committer | Moncef Mechri <moncef.mechri@gmail.com> | 2015-08-11 03:54:54 +0200 |
| commit | 333f998123f617c6e643103184142d67c090c7fd (patch) | |
| tree | c15cee7b0e9bd21d1c591567a75d0bcc5ebf3bc7 /Source/Core/AudioCommon/AlsaSoundStream.cpp | |
| parent | a0c524774386c4543c710958bf1c607a91d6f28c (diff) | |
Don't busy wait in the audio thread (ALSA)
When the emulation is paused and the ALSA backend is used, make the audio
thread wait on a condition variable instead of busy-waiting. This commit
fixes bug #7729
Since the ALSA API is not thread-safe, calls to snd_pcm_drop() and snd_pcm_prepare()
in AlsaSound::Clear() are protected by the same mutex as the condition variable in AlsaSound::SoundLoop()
to make sure that we do not call these functions while a call to
snd_pcm_writei() is ongoing.
Diffstat (limited to 'Source/Core/AudioCommon/AlsaSoundStream.cpp')
| -rw-r--r-- | Source/Core/AudioCommon/AlsaSoundStream.cpp | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/Source/Core/AudioCommon/AlsaSoundStream.cpp b/Source/Core/AudioCommon/AlsaSoundStream.cpp index ae888564b3..3a1f460133 100644 --- a/Source/Core/AudioCommon/AlsaSoundStream.cpp +++ b/Source/Core/AudioCommon/AlsaSoundStream.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include <mutex> + #include "AudioCommon/AlsaSoundStream.h" #include "Common/CommonTypes.h" #include "Common/Thread.h" @@ -39,6 +41,10 @@ bool AlsaSound::Start() void AlsaSound::Stop() { m_thread_status.store(ALSAThreadStatus::STOPPING); + + //Give the opportunity to the audio thread + //to realize we are stopping the emulation + cv.notify_one(); thread.join(); } @@ -53,8 +59,11 @@ void AlsaSound::SoundLoop() Common::SetCurrentThreadName("Audio thread - alsa"); while (m_thread_status.load() == ALSAThreadStatus::RUNNING) { + std::unique_lock<std::mutex> lock(cv_m); + cv.wait(lock, [this]{return !m_muted || m_thread_status.load() != ALSAThreadStatus::RUNNING;}); + m_mixer->Mix(reinterpret_cast<short *>(mix_buffer), frames_to_deliver); - int rc = m_muted ? 1337 : snd_pcm_writei(handle, mix_buffer, frames_to_deliver); + int rc = snd_pcm_writei(handle, mix_buffer, frames_to_deliver); if (rc == -EPIPE) { // Underrun @@ -69,6 +78,24 @@ void AlsaSound::SoundLoop() m_thread_status.store(ALSAThreadStatus::STOPPED); } + +void AlsaSound::Clear(bool muted) +{ + m_muted = muted; + if (m_muted) + { + std::lock_guard<std::mutex> lock(cv_m); + snd_pcm_drop(handle); + } + else + { + std::unique_lock<std::mutex> lock(cv_m); + snd_pcm_prepare(handle); + lock.unlock(); + cv.notify_one(); + } +} + bool AlsaSound::AlsaInit() { unsigned int sample_rate = m_mixer->GetSampleRate(); |
