Commit 0be5a6ab authored by Max Kellermann's avatar Max Kellermann

DecoderControl: reduce the number of PlayerThread wakeups

Wake up the PlayerThread only if it is really waiting for the decoder. This greatly reduces the number of system calls in the DecoderThread.
parent 9802e748
...@@ -30,6 +30,7 @@ DecoderControl::DecoderControl(Mutex &_mutex, Cond &_client_cond) ...@@ -30,6 +30,7 @@ DecoderControl::DecoderControl(Mutex &_mutex, Cond &_client_cond)
:mutex(_mutex), client_cond(_client_cond), :mutex(_mutex), client_cond(_client_cond),
state(DecoderState::STOP), state(DecoderState::STOP),
command(DecoderCommand::NONE), command(DecoderCommand::NONE),
client_is_waiting(false),
song(nullptr), song(nullptr),
replay_gain_db(0), replay_gain_prev_db(0) {} replay_gain_db(0), replay_gain_prev_db(0) {}
...@@ -41,6 +42,18 @@ DecoderControl::~DecoderControl() ...@@ -41,6 +42,18 @@ DecoderControl::~DecoderControl()
song->Free(); song->Free();
} }
void
DecoderControl::WaitForDecoder()
{
assert(!client_is_waiting);
client_is_waiting = true;
client_cond.wait(mutex);
assert(client_is_waiting);
client_is_waiting = false;
}
bool bool
DecoderControl::IsCurrentSong(const Song &_song) const DecoderControl::IsCurrentSong(const Song &_song) const
{ {
......
...@@ -97,6 +97,14 @@ struct DecoderControl { ...@@ -97,6 +97,14 @@ struct DecoderControl {
Error error; Error error;
bool quit; bool quit;
/**
* Is the client currently waiting for the DecoderThread? If
* false, the DecoderThread may omit invoking Cond::signal(),
* reducing the number of system calls.
*/
bool client_is_waiting;
bool seek_error; bool seek_error;
bool seekable; bool seekable;
double seek_where; double seek_where;
...@@ -193,10 +201,10 @@ struct DecoderControl { ...@@ -193,10 +201,10 @@ struct DecoderControl {
* Waits for a signal from the decoder thread. This object * Waits for a signal from the decoder thread. This object
* must be locked prior to calling this function. This method * must be locked prior to calling this function. This method
* is only valid in the player thread. * is only valid in the player thread.
*
* Caller must hold the lock.
*/ */
void WaitForDecoder() { void WaitForDecoder();
client_cond.wait(mutex);
}
bool IsIdle() const { bool IsIdle() const {
return state == DecoderState::STOP || return state == DecoderState::STOP ||
......
...@@ -102,6 +102,7 @@ decoder_flush_chunk(Decoder &decoder) ...@@ -102,6 +102,7 @@ decoder_flush_chunk(Decoder &decoder)
decoder.chunk = nullptr; decoder.chunk = nullptr;
dc.Lock(); dc.Lock();
dc.client_cond.signal(); if (dc.client_is_waiting)
dc.client_cond.signal();
dc.Unlock(); dc.Unlock();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment