From 2a8eacdbfc5d98b016c480ddaddff100301f721f Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Thu, 17 Nov 2011 17:55:02 +0000 Subject: Buflib: Make shrinking and buflib_available() smarter. * shrinking now considers freespace just before the alloc-to-be-shrinked, that means less (or sometimes none at all) is taken from the audio buffer. * core_available() now searches for the best free space, instead of simply the end, i.e. it will not return 0 if the audio buffer is allocated and there's free space before it. It also runs a compaction to ensure maximum contiguous memory. audio_buffer_available() is also enhanced. It now considers the 256K reserve buffer, and returns free buflib space instead if the audio buffer is short. This all fixes the root problem of FS#12344 (Sansa Clip+: PANIC occurred when dircache is enabled), that alloced from the audio buffer, even if it was very short and buflib had many more available as free space before it. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31006 a1c6a512-1295-4272-9138-f99709370657 --- apps/playback.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'apps/playback.c') diff --git a/apps/playback.c b/apps/playback.c index a245091d91..d591998bec 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -733,13 +733,24 @@ static void scratch_mem_init(void *mem) } static int audiobuf_handle; +#define AUDIO_BUFFER_RESERVE (256*1024) static size_t filebuflen; + +size_t audio_buffer_size(void) +{ + if (audiobuf_handle > 0) + return filebuflen - AUDIO_BUFFER_RESERVE; + return 0; +} + size_t audio_buffer_available(void) { - if (audiobuf_handle > 0) /* if allocated return what we got */ - return filebuflen; - return core_available(); + size_t size = 0; + size_t core_size = core_available(); + if (audiobuf_handle > 0) /* if allocated return what we can give */ + size = filebuflen - AUDIO_BUFFER_RESERVE - 128; + return MAX(core_size, size); } /* Set up the audio buffer for playback @@ -840,7 +851,7 @@ static int shrink_callback(int handle, unsigned hints, void* start, size_t old_s size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK); ssize_t size = (ssize_t)old_size - wanted_size; /* keep at least 256K for the buffering */ - if ((size - extradata_size) < 256*1024) + if ((size - extradata_size) < AUDIO_BUFFER_RESERVE) return BUFLIB_CB_CANNOT_SHRINK; -- cgit v1.2.3