summaryrefslogtreecommitdiff
path: root/Source/Core/AudioCommon/AlsaSoundStream.cpp
diff options
context:
space:
mode:
authorMoncef Mechri <moncef.mechri@gmail.com>2015-07-07 15:30:27 +0200
committerMoncef Mechri <moncef.mechri@gmail.com>2015-08-11 03:54:54 +0200
commit333f998123f617c6e643103184142d67c090c7fd (patch)
treec15cee7b0e9bd21d1c591567a75d0bcc5ebf3bc7 /Source/Core/AudioCommon/AlsaSoundStream.cpp
parenta0c524774386c4543c710958bf1c607a91d6f28c (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.cpp29
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();