1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Thomas Martitz 2011-11-17 17:55:02 +00:00
parent 91206954aa
commit 2a8eacdbfc
5 changed files with 104 additions and 20 deletions

View file

@ -179,7 +179,7 @@ static const char* info_getname(int selected_item, void *data,
case INFO_BUFFER: /* buffer */
{
long kib = audio_buffer_available() / 1024; /* to KiB */
long kib = audio_buffer_size() / 1024; /* to KiB */
output_dyn_value(s1, sizeof(s1), kib, kbyte_units, true);
snprintf(buffer, buffer_len, "%s %s", str(LANG_BUFFER_STAT), s1);
}
@ -261,7 +261,7 @@ static int info_speak_item(int selected_item, void * data)
case INFO_BUFFER: /* buffer */
{
talk_id(LANG_BUFFER_STAT, false);
long kib = audio_buffer_available() / 1024; /* to KiB */
long kib = audio_buffer_size() / 1024; /* to KiB */
output_dyn_value(NULL, 0, kib, kbyte_units, true);
break;
}

View file

@ -151,7 +151,7 @@ static bool paused; /* playback is paused */
static int audiobuf_handle; /* handle to the audio buffer */
static char* mpeg_audiobuf; /* poiunter to the audio buffer */
static long audiobuflen; /* length of the audio buffer */
#define AUDIO_BUFFER_RESERVE (256*1024)
#ifdef SIMULATOR
static char mpeg_stack[DEFAULT_STACK_SIZE];
static struct mp3entry taginfo;
@ -515,9 +515,16 @@ static void audio_reset_buffer_noalloc(void* buf, size_t bufsize);
/* Buffer must not move. */
static int shrink_callback(int handle, unsigned hints, void* start, size_t old_size)
{
long offset = audio_current_track()->offset;
bool playing = (audio_status() & AUDIO_STATUS_PLAY) == AUDIO_STATUS_PLAY;
ssize_t extradata_size = old_size - audiobuflen;
/* check what buflib requests */
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) < AUDIO_BUFFER_RESERVE)
return BUFLIB_CB_CANNOT_SHRINK;
/* TODO: Do it without stopping playback, if possible */
bool playing = (audio_status() & AUDIO_STATUS_PLAY) == AUDIO_STATUS_PLAY;
long offset = audio_current_track()->offset;
/* don't call audio_hard_stop() as it frees this handle */
if (thread_self() == audio_thread_id)
{ /* inline case MPEG_STOP (audio_stop()) response
@ -528,9 +535,6 @@ static int shrink_callback(int handle, unsigned hints, void* start, size_t old_s
audio_stop();
talk_buffer_steal(); /* we obtain control over the buffer */
/* we should be free to change the buffer now */
size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK);
ssize_t size = (ssize_t)old_size - wanted_size;
switch (hints & BUFLIB_SHRINK_POS_MASK)
{
case BUFLIB_SHRINK_POS_BACK:
@ -2742,11 +2746,20 @@ void audio_set_recording_options(struct audio_recording_options *options)
#endif /* SIMULATOR */
#endif /* CONFIG_CODEC == MAS3587F */
size_t audio_buffer_available(void)
size_t audio_buffer_size(void)
{
if (audiobuf_handle > 0)
return audiobuflen;
return core_available();
return 0;
}
size_t audio_buffer_available(void)
{
size_t size = 0;
size_t core_size = core_available();
if (audiobuf_handle > 0)
return audiobuflen - AUDIO_BUFFER_RESERVE - 128;
return MAX(core_size, size);
}
static void audio_reset_buffer_noalloc(void* buf, size_t bufsize)

View file

@ -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;