mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-07 08:29:58 +00:00
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.
This commit is contained in:
parent
4a8683ea68
commit
a089125d0f
|
@ -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(); });
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue