diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-12-22 21:33:33 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-12-25 23:54:07 +0100 |
commit | a089125d0fecbe01f072580b464c3c78341771f7 (patch) | |
tree | ac6c2f3fd8302f04813f05668a421352e2a48a41 /Servers | |
parent | 4a8683ea686c1c6fb11a2641a0e7a2e5fe8ca9f5 (diff) | |
download | serenity-a089125d0fecbe01f072580b464c3c78341771f7.zip |
AudioServer: Block the mixer thread when there's nothing to do
Use a pthread_cond_t to have the ASMixer thread wait until a client has
connected and added a buffer queue to the "pending mixing" vector.
This solves the long-standing issue of the system "idling" at ~8% CPU.
Diffstat (limited to 'Servers')
-rw-r--r-- | Servers/AudioServer/ASMixer.cpp | 31 | ||||
-rw-r--r-- | Servers/AudioServer/ASMixer.h | 3 |
2 files changed, 19 insertions, 15 deletions
diff --git a/Servers/AudioServer/ASMixer.cpp b/Servers/AudioServer/ASMixer.cpp index 97c4a19e1f..2a35751f74 100644 --- a/Servers/AudioServer/ASMixer.cpp +++ b/Servers/AudioServer/ASMixer.cpp @@ -2,19 +2,25 @@ #include <AudioServer/ASClientConnection.h> #include <AudioServer/ASMixer.h> #include <limits> +#include <pthread.h> ASMixer::ASMixer() : m_device(CFile::construct("/dev/audio", this)) - , m_sound_thread([this] { - mix(); - return 0; - }, "AudioServer[mixer]") + , m_sound_thread( + [this] { + mix(); + return 0; + }, + "AudioServer[mixer]") { if (!m_device->open(CIODevice::WriteOnly)) { dbgprintf("Can't open audio device: %s\n", m_device->error_string()); return; } + pthread_mutex_init(&m_pending_mutex, nullptr); + pthread_cond_init(&m_pending_cond, nullptr); + m_zero_filled_buffer = (u8*)malloc(4096); bzero(m_zero_filled_buffer, 4096); m_sound_thread.start(); @@ -26,9 +32,11 @@ ASMixer::~ASMixer() NonnullRefPtr<ASBufferQueue> ASMixer::create_queue(ASClientConnection& client) { - LOCKER(m_lock); auto queue = adopt(*new ASBufferQueue(client)); + pthread_mutex_lock(&m_pending_mutex); m_pending_mixing.append(*queue); + pthread_cond_signal(&m_pending_cond); + pthread_mutex_unlock(&m_pending_mutex); return queue; } @@ -37,16 +45,11 @@ void ASMixer::mix() decltype(m_pending_mixing) active_mix_queues; for (;;) { - { - LOCKER(m_lock); + if (active_mix_queues.is_empty()) { + pthread_mutex_lock(&m_pending_mutex); + pthread_cond_wait(&m_pending_cond, &m_pending_mutex); active_mix_queues.append(move(m_pending_mixing)); - } - - // ### use a wakeup of some kind rather than this garbage - if (active_mix_queues.size() == 0) { - // nothing to mix yet - usleep(10000); - continue; + pthread_mutex_unlock(&m_pending_mutex); } active_mix_queues.remove_all_matching([&](auto& entry) { return !entry->client(); }); diff --git a/Servers/AudioServer/ASMixer.h b/Servers/AudioServer/ASMixer.h index 5de1b624fc..c502536745 100644 --- a/Servers/AudioServer/ASMixer.h +++ b/Servers/AudioServer/ASMixer.h @@ -96,9 +96,10 @@ public: private: Vector<NonnullRefPtr<ASBufferQueue>> m_pending_mixing; + pthread_mutex_t m_pending_mutex; + pthread_cond_t m_pending_cond; RefPtr<CFile> m_device; - LibThread::Lock m_lock; LibThread::Thread m_sound_thread; |