Use the core codec thread's stack for the mpegplayer audio thread - this will free up another 9KB of IRAM for use by mpegplayer

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15181 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Dave Chapman 2007-10-18 08:56:32 +00:00
parent fa1a38e7ce
commit c5263a4a13

View file

@ -41,13 +41,8 @@ mpegplayer is structured as follows:
Using the main thread for buffering wastes the 8KB main stack which is Using the main thread for buffering wastes the 8KB main stack which is
in IRAM. However, 8KB is not enough for the audio thread to run (it in IRAM. However, 8KB is not enough for the audio thread to run (it
needs somewhere between 8KB and 9KB), so we create a new thread in needs somewhere between 8KB and 9KB), so we create a new thread in
order to`give it a larger stack. order to`give it a larger stack and steal the core codec thread's
stack (9KB of precious IRAM).
We use 4.5KB of the main stack for a libmad buffer (making use of
otherwise unused IRAM). There is also the possiblity of stealing the
main Rockbox codec thread's 9KB of IRAM stack and using that for
mpegplayer's audio thread - but we should only implement that if we
can put the IRAM to good use.
The button loop (and hence pause/resume, main menu and, in the future, The button loop (and hence pause/resume, main menu and, in the future,
seeking) is placed in the audio thread. This keeps it on the main CPU seeking) is placed in the audio thread. This keeps it on the main CPU
@ -1489,11 +1484,10 @@ audio_thread_quit:
/* End of libmad stuff */ /* End of libmad stuff */
/* TODO: Running in the main thread, libmad needs 8.25KB of stack. /* The audio stack is stolen from the core codec thread */
The codec thread uses a 9KB stack. So we can probable reduce this a
little, but leave at 9KB for now to be safe. */
#define AUDIO_STACKSIZE (9*1024) #define AUDIO_STACKSIZE (9*1024)
uint32_t audio_stack[AUDIO_STACKSIZE / sizeof(uint32_t)] IBSS_ATTR; static uint32_t codec_stack_copy[AUDIO_STACKSIZE / sizeof(uint32_t)];
uint32_t* audio_stack;
/* TODO: Check if 4KB is appropriate - it works for my test streams, /* TODO: Check if 4KB is appropriate - it works for my test streams,
so maybe we can reduce it. */ so maybe we can reduce it. */
@ -2214,6 +2208,8 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
int in_file; int in_file;
size_t disk_buf_len; size_t disk_buf_len;
ssize_t seek_pos; ssize_t seek_pos;
size_t audio_stack_size = 0; /* Keep gcc happy and init */
int i;
#ifndef HAVE_LCD_COLOR #ifndef HAVE_LCD_COLOR
long graysize; long graysize;
int grayscales; int grayscales;
@ -2314,6 +2310,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
find_start_pts( in_file ); find_start_pts( in_file );
find_end_pts( in_file ); find_end_pts( in_file );
/* start menu */ /* start menu */
rb->lcd_clear_display(); rb->lcd_clear_display();
rb->lcd_update(); rb->lcd_update();
@ -2346,6 +2343,43 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
cannot just return PLUGIN_ERROR - instead drop though to cleanup code cannot just return PLUGIN_ERROR - instead drop though to cleanup code
*/ */
#ifdef SIMULATOR
/* The simulator thread implementation doesn't have stack buffers, and
these parameters are ignored. */
(void)i; /* Keep gcc happy */
audio_stack = NULL;
audio_stack_size = 0;
#else
/* Borrow the codec thread's stack (in IRAM on most targets) */
audio_stack = NULL;
for (i = 0; i < MAXTHREADS; i++)
{
if (rb->strcmp(rb->threads[i].name,"codec")==0)
{
/* Wait to ensure the codec thread has blocked */
while (rb->threads[i].state!=STATE_BLOCKED)
rb->yield();
/* Now we can steal the stack */
audio_stack = rb->threads[i].stack;
audio_stack_size = rb->threads[i].stack_size;
/* Backup the codec thread's stack */
rb->memcpy(codec_stack_copy,audio_stack,audio_stack_size);
break;
}
}
if (audio_stack == NULL)
{
/* This shouldn't happen, but deal with it anyway by using
the copy instead */
audio_stack = codec_stack_copy;
audio_stack_size = AUDIO_STACKSIZE;
}
#endif
rb->splash(0, "Loading..."); rb->splash(0, "Loading...");
/* seek start time */ /* seek start time */
@ -2391,7 +2425,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
rb->splash(HZ, "Cannot create video thread!"); rb->splash(HZ, "Cannot create video thread!");
} }
else if ((audio_str.thread = rb->create_thread(audio_thread, else if ((audio_str.thread = rb->create_thread(audio_thread,
(uint8_t*)audio_stack,AUDIO_STACKSIZE, 0,"mpgaudio" (uint8_t*)audio_stack,audio_stack_size, 0,"mpgaudio"
IF_PRIO(,PRIORITY_PLAYBACK) IF_COP(, CPU))) == NULL) IF_PRIO(,PRIORITY_PLAYBACK) IF_COP(, CPU))) == NULL)
{ {
rb->splash(HZ, "Cannot create audio thread!"); rb->splash(HZ, "Cannot create audio thread!");
@ -2479,6 +2513,11 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
rb->close (in_file); rb->close (in_file);
#ifndef SIMULATOR
/* Restore the codec thread's stack */
rb->memcpy(audio_stack, codec_stack_copy, audio_stack_size);
#endif
#ifdef HAVE_ADJUSTABLE_CPU_FREQ #ifdef HAVE_ADJUSTABLE_CPU_FREQ
rb->cpu_boost(false); rb->cpu_boost(false);
#endif #endif