summaryrefslogtreecommitdiff
path: root/Servers
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-12-22 21:33:33 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-12-25 23:54:07 +0100
commita089125d0fecbe01f072580b464c3c78341771f7 (patch)
treeac6c2f3fd8302f04813f05668a421352e2a48a41 /Servers
parent4a8683ea686c1c6fb11a2641a0e7a2e5fe8ca9f5 (diff)
downloadserenity-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.cpp31
-rw-r--r--Servers/AudioServer/ASMixer.h3
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;