cache: throttle wakeups

In the extreme case, reading 1 byte would wake up the cache to make the
cache thread read 1 byte. This would be extremely inefficient. This will
not normally happen in our cache implementation, but it's still present
to some lesser degree. Normally you'd set a predefined "cache too low"
boundary, after which you would restart reading. For some reason
something like this is already present using a hardcoded value
(FILL_LIMIT - I don't even know the deeper reason why this exists). So
use that to reduce wakeups.

This doesn't fix redundant wakeups on EOFs, which is especially visible
should something keep retrying reading on EOF (like in an endless loop).
This commit is contained in:
wm4 2017-10-20 22:13:22 +02:00
parent 13fb166d87
commit 7163c95cfd
1 changed files with 14 additions and 2 deletions

View File

@ -109,6 +109,7 @@ struct priv {
// Owned by the cache thread
stream_t *stream; // "real" stream, used to read from the source media
int64_t bytes_until_wakeup; // wakeup cache thread after this many bytes
// All the following members are shared between the threads.
// You must lock the mutex to access them.
@ -602,8 +603,17 @@ static int cache_fill_buffer(struct stream *cache, char *buffer, int max_len)
}
}
// wakeup the cache thread, possibly make it read more data ahead
pthread_cond_signal(&s->wakeup);
if (!s->eof) {
// wakeup the cache thread, possibly make it read more data ahead
// this is throttled to reduce excessive wakeups during normal reading
// (using the amount of bytes after which the cache thread most likely
// can actually read new data)
s->bytes_until_wakeup -= readb;
if (s->bytes_until_wakeup <= 0) {
s->bytes_until_wakeup = MPMAX(FILL_LIMIT, s->stream->read_chunk);
pthread_cond_signal(&s->wakeup);
}
}
pthread_mutex_unlock(&s->mutex);
return readb;
}
@ -649,6 +659,8 @@ static int cache_seek(stream_t *cache, int64_t pos)
}
}
s->bytes_until_wakeup = 0;
pthread_mutex_unlock(&s->mutex);
return r;