summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2009-01-05 10:31:19 +0000
committerMichael Sevakis <jethead71@rockbox.org>2009-01-05 10:31:19 +0000
commit2054627caa7f71c564ce35b4525b6281fcd2cc39 (patch)
tree2b0aa3b9b8888c4746b75d4750d90f79552159ee
parent45aa9a22f9a3e08505cc2f2999459d249356ed9c (diff)
downloadrockbox-2054627caa7f71c564ce35b4525b6281fcd2cc39.tar.gz
rockbox-2054627caa7f71c564ce35b4525b6281fcd2cc39.zip
Have the codec thread do callbacks instead of messing with the stack which is much simpler and safer. Remove threads array from plugin API since it now serves no purpose. Up minimum API version and sort.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19684 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/playback.c21
-rw-r--r--apps/playback.h2
-rw-r--r--apps/plugin.c10
-rw-r--r--apps/plugin.h13
-rw-r--r--apps/plugins/mpegplayer/audio_thread.c75
-rw-r--r--apps/plugins/test_codec.c60
6 files changed, 56 insertions, 125 deletions
diff --git a/apps/playback.c b/apps/playback.c
index 0f76666c1e..91f85f9408 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -150,6 +150,8 @@ enum {
150 Q_ENCODER_LOAD_DISK, 150 Q_ENCODER_LOAD_DISK,
151 Q_ENCODER_RECORD, 151 Q_ENCODER_RECORD,
152#endif 152#endif
153
154 Q_CODEC_DO_CALLBACK,
153}; 155};
154 156
155enum filling_state { 157enum filling_state {
@@ -1303,6 +1305,13 @@ static void codec_thread(void)
1303 status = codec_load_buf(CUR_TI->codec_hid, &ci); 1305 status = codec_load_buf(CUR_TI->codec_hid, &ci);
1304 break; 1306 break;
1305 1307
1308 case Q_CODEC_DO_CALLBACK:
1309 LOGFQUEUE("codec < Q_CODEC_DO_CALLBACK");
1310 queue_reply(&codec_queue, 1);
1311 if ((void*)ev.data != NULL)
1312 ((void (*)(void))ev.data)();
1313 break;
1314
1306#ifdef AUDIO_HAVE_RECORDING 1315#ifdef AUDIO_HAVE_RECORDING
1307 case Q_ENCODER_LOAD_DISK: 1316 case Q_ENCODER_LOAD_DISK:
1308 LOGFQUEUE("codec < Q_ENCODER_LOAD_DISK"); 1317 LOGFQUEUE("codec < Q_ENCODER_LOAD_DISK");
@@ -1419,6 +1428,18 @@ static void codec_thread(void)
1419 } 1428 }
1420} 1429}
1421 1430
1431/* Borrow the codec thread and return the ID */
1432void codec_thread_do_callback(void (*fn)(void), unsigned int *id)
1433{
1434 /* Set id before telling thread to call something; it may be
1435 * needed before this function returns. */
1436 if (id != NULL)
1437 *id = codec_thread_id;
1438
1439 /* Codec thread will signal just before entering callback */
1440 LOGFQUEUE("codec >| Q_CODEC_DO_CALLBACK");
1441 queue_send(&codec_queue, Q_CODEC_DO_CALLBACK, (intptr_t)fn);
1442}
1422 1443
1423/* --- Buffering callbacks --- */ 1444/* --- Buffering callbacks --- */
1424 1445
diff --git a/apps/playback.h b/apps/playback.h
index e65d5da150..3fcb454cc9 100644
--- a/apps/playback.h
+++ b/apps/playback.h
@@ -42,6 +42,8 @@ enum
42 AUDIO_WANT_VOICE, 42 AUDIO_WANT_VOICE,
43}; 43};
44bool audio_restore_playback(int type); /* Restores the audio buffer to handle the requested playback */ 44bool audio_restore_playback(int type); /* Restores the audio buffer to handle the requested playback */
45void codec_thread_do_callback(void (*fn)(void),
46 unsigned int *codec_thread_id);
45 47
46#ifdef HAVE_ALBUMART 48#ifdef HAVE_ALBUMART
47int audio_current_aa_hid(void); 49int audio_current_aa_hid(void);
diff --git a/apps/plugin.c b/apps/plugin.c
index 3efd31ccc9..cc0a94bb38 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -71,8 +71,6 @@ static char current_plugin[MAX_PATH];
71 71
72char *plugin_get_current_filename(void); 72char *plugin_get_current_filename(void);
73 73
74extern struct thread_entry threads[MAXTHREADS];
75
76static const struct plugin_api rockbox_api = { 74static const struct plugin_api rockbox_api = {
77 75
78 /* lcd */ 76 /* lcd */
@@ -293,11 +291,14 @@ static const struct plugin_api rockbox_api = {
293 &current_tick, 291 &current_tick,
294 default_event_handler, 292 default_event_handler,
295 default_event_handler_ex, 293 default_event_handler_ex,
296 threads,
297 create_thread, 294 create_thread,
298 thread_exit, 295 thread_exit,
299 thread_wait, 296 thread_wait,
300#if (CONFIG_CODEC == SWCODEC) 297#if (CONFIG_CODEC == SWCODEC)
298 thread_thaw,
299#ifdef HAVE_PRIORITY_SCHEDULING
300 thread_set_priority,
301#endif
301 mutex_init, 302 mutex_init,
302 mutex_lock, 303 mutex_lock,
303 mutex_unlock, 304 mutex_unlock,
@@ -544,6 +545,7 @@ static const struct plugin_api rockbox_api = {
544 &global_status, 545 &global_status,
545 talk_disable, 546 talk_disable,
546#if CONFIG_CODEC == SWCODEC 547#if CONFIG_CODEC == SWCODEC
548 codec_thread_do_callback,
547 codec_load_file, 549 codec_load_file,
548 get_codec_filename, 550 get_codec_filename,
549 get_metadata, 551 get_metadata,
@@ -611,8 +613,6 @@ static const struct plugin_api rockbox_api = {
611 search_albumart_files, 613 search_albumart_files,
612#endif 614#endif
613 615
614 thread_thaw,
615
616#ifdef HAVE_SEMAPHORE_OBJECTS 616#ifdef HAVE_SEMAPHORE_OBJECTS
617 semaphore_init, 617 semaphore_init,
618 semaphore_wait, 618 semaphore_wait,
diff --git a/apps/plugin.h b/apps/plugin.h
index a06f009520..390a65c7ad 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -132,12 +132,12 @@ void* plugin_get_buffer(size_t *buffer_size);
132#define PLUGIN_MAGIC 0x526F634B /* RocK */ 132#define PLUGIN_MAGIC 0x526F634B /* RocK */
133 133
134/* increase this every time the api struct changes */ 134/* increase this every time the api struct changes */
135#define PLUGIN_API_VERSION 134 135#define PLUGIN_API_VERSION 135
136 136
137/* update this to latest version if a change to the api struct breaks 137/* update this to latest version if a change to the api struct breaks
138 backwards compatibility (and please take the opportunity to sort in any 138 backwards compatibility (and please take the opportunity to sort in any
139 new function which are "waiting" at the end of the function table) */ 139 new function which are "waiting" at the end of the function table) */
140#define PLUGIN_MIN_API_VERSION 134 140#define PLUGIN_MIN_API_VERSION 135
141 141
142/* plugin return codes */ 142/* plugin return codes */
143enum plugin_status { 143enum plugin_status {
@@ -410,7 +410,6 @@ struct plugin_api {
410 volatile long* current_tick; 410 volatile long* current_tick;
411 long (*default_event_handler)(long event); 411 long (*default_event_handler)(long event);
412 long (*default_event_handler_ex)(long event, void (*callback)(void *), void *parameter); 412 long (*default_event_handler_ex)(long event, void (*callback)(void *), void *parameter);
413 struct thread_entry* threads;
414 unsigned int (*create_thread)(void (*function)(void), void* stack, 413 unsigned int (*create_thread)(void (*function)(void), void* stack,
415 size_t stack_size, unsigned flags, 414 size_t stack_size, unsigned flags,
416 const char *name 415 const char *name
@@ -419,6 +418,10 @@ struct plugin_api {
419 void (*thread_exit)(void); 418 void (*thread_exit)(void);
420 void (*thread_wait)(unsigned int thread_id); 419 void (*thread_wait)(unsigned int thread_id);
421#if CONFIG_CODEC == SWCODEC 420#if CONFIG_CODEC == SWCODEC
421 void (*thread_thaw)(unsigned int thread_id);
422#ifdef HAVE_PRIORITY_SCHEDULING
423 int (*thread_set_priority)(unsigned int thread_id, int priority);
424#endif
422 void (*mutex_init)(struct mutex *m); 425 void (*mutex_init)(struct mutex *m);
423 void (*mutex_lock)(struct mutex *m); 426 void (*mutex_lock)(struct mutex *m);
424 void (*mutex_unlock)(struct mutex *m); 427 void (*mutex_unlock)(struct mutex *m);
@@ -693,6 +696,8 @@ struct plugin_api {
693 struct system_status *global_status; 696 struct system_status *global_status;
694 void (*talk_disable)(bool disable); 697 void (*talk_disable)(bool disable);
695#if CONFIG_CODEC == SWCODEC 698#if CONFIG_CODEC == SWCODEC
699 void (*codec_thread_do_callback)(void (*fn)(void),
700 unsigned int *audio_thread_id);
696 int (*codec_load_file)(const char* codec, struct codec_api *api); 701 int (*codec_load_file)(const char* codec, struct codec_api *api);
697 const char *(*get_codec_filename)(int cod_spec); 702 const char *(*get_codec_filename)(int cod_spec);
698 bool (*get_metadata)(struct mp3entry* id3, int fd, const char* trackname); 703 bool (*get_metadata)(struct mp3entry* id3, int fd, const char* trackname);
@@ -775,8 +780,6 @@ struct plugin_api {
775 char *buf, int buflen); 780 char *buf, int buflen);
776#endif 781#endif
777 782
778 void (*thread_thaw)(unsigned int thread_id);
779
780#ifdef HAVE_SEMAPHORE_OBJECTS 783#ifdef HAVE_SEMAPHORE_OBJECTS
781 void (*semaphore_init)(struct semaphore *s, int max, int start); 784 void (*semaphore_init)(struct semaphore *s, int max, int start);
782 void (*semaphore_wait)(struct semaphore *s); 785 void (*semaphore_wait)(struct semaphore *s);
diff --git a/apps/plugins/mpegplayer/audio_thread.c b/apps/plugins/mpegplayer/audio_thread.c
index 2fb46efd56..f6552218b0 100644
--- a/apps/plugins/mpegplayer/audio_thread.c
+++ b/apps/plugins/mpegplayer/audio_thread.c
@@ -38,14 +38,7 @@ struct audio_thread_data
38 struct dsp_config *dsp; /* The DSP we're using */ 38 struct dsp_config *dsp; /* The DSP we're using */
39}; 39};
40 40
41/* The audio stack is stolen from the core codec thread (but not in uisim) */ 41/* The audio thread is stolen from the core codec thread */
42/* Used for stealing codec thread's stack */
43static uint32_t* audio_stack;
44static size_t audio_stack_size; /* Keep gcc happy and init */
45#define AUDIO_STACKSIZE (9*1024)
46#ifndef SIMULATOR
47static uint32_t codec_stack_copy[AUDIO_STACKSIZE / sizeof(uint32_t)];
48#endif
49static struct event_queue audio_str_queue SHAREDBSS_ATTR; 42static struct event_queue audio_str_queue SHAREDBSS_ATTR;
50static struct queue_sender_list audio_str_queue_send SHAREDBSS_ATTR; 43static struct queue_sender_list audio_str_queue_send SHAREDBSS_ATTR;
51struct stream audio_str IBSS_ATTR; 44struct stream audio_str IBSS_ATTR;
@@ -473,6 +466,11 @@ static void audio_thread_msg(struct audio_thread_data *td)
473static void audio_thread(void) 466static void audio_thread(void)
474{ 467{
475 struct audio_thread_data td; 468 struct audio_thread_data td;
469#ifdef HAVE_PRIORITY_SCHEDULING
470 /* Up the priority since the core DSP over-yields internally */
471 int old_priority = rb->thread_set_priority(THREAD_ID_CURRENT,
472 PRIORITY_PLAYBACK-4);
473#endif
476 474
477 rb->memset(&td, 0, sizeof (td)); 475 rb->memset(&td, 0, sizeof (td));
478 td.status = STREAM_STOPPED; 476 td.status = STREAM_STOPPED;
@@ -512,7 +510,13 @@ static void audio_thread(void)
512 case TSTATE_RENDER_WAIT: goto render_wait; 510 case TSTATE_RENDER_WAIT: goto render_wait;
513 case TSTATE_RENDER_WAIT_END: goto render_wait_end; 511 case TSTATE_RENDER_WAIT_END: goto render_wait_end;
514 /* Anything else is interpreted as an exit */ 512 /* Anything else is interpreted as an exit */
515 default: return; 513 default:
514 {
515#ifdef HAVE_PRIORITY_SCHEDULING
516 rb->thread_set_priority(THREAD_ID_CURRENT, old_priority);
517#endif
518 return;
519 }
516 } 520 }
517 } 521 }
518 522
@@ -677,43 +681,6 @@ static void audio_thread(void)
677/* Initializes the audio thread resources and starts the thread */ 681/* Initializes the audio thread resources and starts the thread */
678bool audio_thread_init(void) 682bool audio_thread_init(void)
679{ 683{
680 int i;
681#ifdef SIMULATOR
682 /* The simulator thread implementation doesn't have stack buffers, and
683 these parameters are ignored. */
684 (void)i; /* Keep gcc happy */
685 audio_stack = NULL;
686 audio_stack_size = 0;
687#else
688 /* Borrow the codec thread's stack (in IRAM on most targets) */
689 audio_stack = NULL;
690 for (i = 0; i < MAXTHREADS; i++)
691 {
692 if (rb->strcmp(rb->threads[i].name, "codec") == 0)
693 {
694 /* Wait to ensure the codec thread has blocked */
695 while (rb->threads[i].state != STATE_BLOCKED)
696 rb->yield();
697
698 /* Now we can steal the stack */
699 audio_stack = rb->threads[i].stack;
700 audio_stack_size = rb->threads[i].stack_size;
701
702 /* Backup the codec thread's stack */
703 rb->memcpy(codec_stack_copy, audio_stack, audio_stack_size);
704 break;
705 }
706 }
707
708 if (audio_stack == NULL)
709 {
710 /* This shouldn't happen, but deal with it anyway by using
711 the copy instead */
712 audio_stack = codec_stack_copy;
713 audio_stack_size = AUDIO_STACKSIZE;
714 }
715#endif
716
717 /* Initialise the encoded audio buffer and its descriptors */ 684 /* Initialise the encoded audio buffer and its descriptors */
718 audio_queue.start = mpeg_malloc(AUDIOBUF_ALLOC_SIZE, 685 audio_queue.start = mpeg_malloc(AUDIOBUF_ALLOC_SIZE,
719 MPEG_ALLOC_AUDIOBUF); 686 MPEG_ALLOC_AUDIOBUF);
@@ -724,17 +691,12 @@ bool audio_thread_init(void)
724 audio_str.hdr.q = &audio_str_queue; 691 audio_str.hdr.q = &audio_str_queue;
725 rb->queue_init(audio_str.hdr.q, false); 692 rb->queue_init(audio_str.hdr.q, false);
726 693
727 /* One-up on the priority since the core DSP over-yields internally */ 694 /* We steal the codec thread for audio */
728 audio_str.thread = rb->create_thread( 695 rb->codec_thread_do_callback(audio_thread, &audio_str.thread);
729 audio_thread, audio_stack, audio_stack_size, 0,
730 "mpgaudio" IF_PRIO(,PRIORITY_PLAYBACK-4) IF_COP(, CPU));
731 696
732 rb->queue_enable_queue_send(audio_str.hdr.q, &audio_str_queue_send, 697 rb->queue_enable_queue_send(audio_str.hdr.q, &audio_str_queue_send,
733 audio_str.thread); 698 audio_str.thread);
734 699
735 if (audio_str.thread == 0)
736 return false;
737
738 /* Wait for thread to initialize */ 700 /* Wait for thread to initialize */
739 str_send_msg(&audio_str, STREAM_NULL, 0); 701 str_send_msg(&audio_str, STREAM_NULL, 0);
740 702
@@ -747,12 +709,7 @@ void audio_thread_exit(void)
747 if (audio_str.thread != 0) 709 if (audio_str.thread != 0)
748 { 710 {
749 str_post_msg(&audio_str, STREAM_QUIT, 0); 711 str_post_msg(&audio_str, STREAM_QUIT, 0);
750 rb->thread_wait(audio_str.thread); 712 rb->codec_thread_do_callback(NULL, NULL);
751 audio_str.thread = 0; 713 audio_str.thread = 0;
752 } 714 }
753
754#ifndef SIMULATOR
755 /* Restore the codec thread's stack */
756 rb->memcpy(audio_stack, codec_stack_copy, audio_stack_size);
757#endif
758} 715}
diff --git a/apps/plugins/test_codec.c b/apps/plugins/test_codec.c
index 17effd8dfd..20a1febd4f 100644
--- a/apps/plugins/test_codec.c
+++ b/apps/plugins/test_codec.c
@@ -513,9 +513,6 @@ static void codec_thread(void)
513 codec_playing = false; 513 codec_playing = false;
514} 514}
515 515
516static uintptr_t* codec_stack;
517static size_t codec_stack_size;
518
519static enum plugin_status test_track(const char* filename) 516static enum plugin_status test_track(const char* filename)
520{ 517{
521 size_t n; 518 size_t n;
@@ -525,7 +522,6 @@ static enum plugin_status test_track(const char* filename)
525 long ticks; 522 long ticks;
526 unsigned long speed; 523 unsigned long speed;
527 unsigned long duration; 524 unsigned long duration;
528 unsigned int codecthread_id;
529 const char* ch; 525 const char* ch;
530 526
531 /* Display filename (excluding any path)*/ 527 /* Display filename (excluding any path)*/
@@ -588,13 +584,7 @@ static enum plugin_status test_track(const char* filename)
588 584
589 codec_playing = true; 585 codec_playing = true;
590 586
591 if ((codecthread_id = rb->create_thread(codec_thread, 587 rb->codec_thread_do_callback(codec_thread, NULL);
592 codec_stack, codec_stack_size, 0, "testcodec"
593 IF_PRIO(,PRIORITY_PLAYBACK) IF_COP(, CPU))) == 0)
594 {
595 log_text("Cannot create codec thread!",true);
596 goto exit;
597 }
598 588
599 /* Wait for codec thread to die */ 589 /* Wait for codec thread to die */
600 while (codec_playing) 590 while (codec_playing)
@@ -606,7 +596,7 @@ static enum plugin_status test_track(const char* filename)
606 ticks = endtick - starttick; 596 ticks = endtick - starttick;
607 597
608 /* Be sure it is done */ 598 /* Be sure it is done */
609 rb->thread_wait(codecthread_id); 599 rb->codec_thread_do_callback(NULL, NULL);
610 600
611 log_text(str,true); 601 log_text(str,true);
612 602
@@ -656,11 +646,9 @@ exit:
656/* plugin entry point */ 646/* plugin entry point */
657enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter) 647enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
658{ 648{
659 uintptr_t* codec_stack_copy;
660 int result, selection = 0; 649 int result, selection = 0;
661 enum plugin_status res = PLUGIN_OK; 650 enum plugin_status res = PLUGIN_OK;
662 int scandir; 651 int scandir;
663 int i;
664 struct dirent *entry; 652 struct dirent *entry;
665 DIR* dir; 653 DIR* dir;
666 char* ch; 654 char* ch;
@@ -676,43 +664,8 @@ enum plugin_status plugin_start(const struct plugin_api* api, const void* parame
676 } 664 }
677 665
678 codec_mallocbuf = rb->plugin_get_audio_buffer(&audiosize); 666 codec_mallocbuf = rb->plugin_get_audio_buffer(&audiosize);
679 667 audiobuf = SKIPBYTES(codec_mallocbuf, CODEC_SIZE);
680#ifdef SIMULATOR 668 audiosize -= CODEC_SIZE;
681 /* The simulator thread implementation doesn't have stack buffers */
682 (void)i;
683 codec_stack_size = 0;
684#else
685 /* Borrow the codec thread's stack (in IRAM on most targets) */
686 codec_stack = NULL;
687 for (i = 0; i < MAXTHREADS; i++)
688 {
689 if (rb->strcmp(rb->threads[i].name,"codec")==0)
690 {
691 /* Wait to ensure the codec thread has blocked */
692 while (rb->threads[i].state!=STATE_BLOCKED)
693 rb->yield();
694
695 codec_stack = rb->threads[i].stack;
696 codec_stack_size = rb->threads[i].stack_size;
697 break;
698 }
699 }
700
701 if (codec_stack == NULL)
702 {
703 rb->splash(HZ*2, "No codec thread!");
704 return PLUGIN_ERROR;
705 }
706#endif
707
708 codec_stack_copy = codec_mallocbuf + CODEC_SIZE;
709 audiobuf = SKIPBYTES(codec_stack_copy, codec_stack_size);
710 audiosize -= CODEC_SIZE + codec_stack_size;
711
712#ifndef SIMULATOR
713 /* Backup the codec thread's stack */
714 rb->memcpy(codec_stack_copy,codec_stack,codec_stack_size);
715#endif
716 669
717#ifdef HAVE_ADJUSTABLE_CPU_FREQ 670#ifdef HAVE_ADJUSTABLE_CPU_FREQ
718 rb->cpu_boost(true); 671 rb->cpu_boost(true);
@@ -803,11 +756,6 @@ enum plugin_status plugin_start(const struct plugin_api* api, const void* parame
803exit: 756exit:
804 log_close(); 757 log_close();
805 758
806#ifndef SIMULATOR
807 /* Restore the codec thread's stack */
808 rb->memcpy(codec_stack, codec_stack_copy, codec_stack_size);
809#endif
810
811#ifdef HAVE_ADJUSTABLE_CPU_FREQ 759#ifdef HAVE_ADJUSTABLE_CPU_FREQ
812 rb->cpu_boost(false); 760 rb->cpu_boost(false);
813#endif 761#endif