From 7e12bba0d26a609ce16e981f0ebd4b8e73f59a8e Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Mon, 22 Oct 2007 05:57:38 +0000 Subject: [PATCH] Phase in thread_wait when waiting for a thread to exit. Begin phasing out the spinlock object for general use; it will become a multicore-only object for core locking. Take care of plugins first. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15260 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugin.c | 8 +++++--- apps/plugin.h | 12 +++++++----- apps/plugins/alpine_cdc.c | 13 +++++-------- apps/plugins/battery_bench.c | 12 ++++-------- apps/plugins/mpegplayer/mpegplayer.c | 29 +++++++++++++++------------- apps/plugins/test_codec.c | 3 +++ 6 files changed, 40 insertions(+), 37 deletions(-) diff --git a/apps/plugin.c b/apps/plugin.c index a8781dd1ac..ff23a55537 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -512,10 +512,12 @@ static const struct plugin_api rockbox_api = { the API gets incompatible */ #if (CONFIG_CODEC == SWCODEC) - spinlock_init, - spinlock_lock, - spinlock_unlock, + mutex_init, + mutex_lock, + mutex_unlock, #endif + + thread_wait, }; int plugin_load(const char* plugin, void* parameter) diff --git a/apps/plugin.h b/apps/plugin.h index 27ab2ce166..9e08dda7c7 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -112,12 +112,12 @@ #define PLUGIN_MAGIC 0x526F634B /* RocK */ /* increase this every time the api struct changes */ -#define PLUGIN_API_VERSION 85 +#define PLUGIN_API_VERSION 86 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any new function which are "waiting" at the end of the function table) */ -#define PLUGIN_MIN_API_VERSION 85 +#define PLUGIN_MIN_API_VERSION 86 /* plugin return codes */ enum plugin_status { @@ -634,10 +634,12 @@ struct plugin_api { the API gets incompatible */ #if (CONFIG_CODEC == SWCODEC) - void (*spinlock_init)(struct spinlock *l IF_COP(, unsigned int flags)); - void (*spinlock_lock)(struct spinlock *l); - void (*spinlock_unlock)(struct spinlock *l); + void (*mutex_init)(struct mutex *m); + void (*mutex_lock)(struct mutex *m); + void (*mutex_unlock)(struct mutex *m); #endif + + void (*thread_wait)(struct thread_entry *thread); }; /* plugin header */ diff --git a/apps/plugins/alpine_cdc.c b/apps/plugins/alpine_cdc.c index 622338742a..919ce181f6 100644 --- a/apps/plugins/alpine_cdc.c +++ b/apps/plugins/alpine_cdc.c @@ -204,7 +204,7 @@ struct { bool foreground; /* set as long as we're owning the UI */ bool exiting; /* signal to the thread that we want to exit */ - bool ended; /* response from the thread, that is has exited */ + struct thread_entry *thread; /* worker thread id */ } gTread; static struct plugin_api* rb; /* here is the global API struct pointer */ @@ -1112,8 +1112,6 @@ void thread(void) } } while (!gTread.exiting); - - gTread.ended = true; /* acknowledge the exit */ } /* callback to end the TSR plugin, called before a new one gets loaded */ @@ -1122,8 +1120,7 @@ bool exit_tsr(bool reenter) if (reenter) return false; /* dont let it start again */ gTread.exiting = true; /* tell the thread to end */ - while (!gTread.ended) /* wait until it did */ - rb->yield(); + rb->thread_wait(gTread.thread); /* wait until it did */ uart_init(BAUDRATE); /* return to standard baudrate */ IPRE = (IPRE & ~0xF000); /* UART interrupt off */ @@ -1167,9 +1164,9 @@ int main(void* parameter) rb->memset(&gTread, 0, sizeof(gTread)); gTread.foreground = true; - rb->create_thread(thread, stack, stacksize, 0, "CDC" - IF_PRIO(, PRIORITY_BACKGROUND) - IF_COP(, CPU)); + gTread.thread = rb->create_thread(thread, stack, stacksize, 0, "CDC" + IF_PRIO(, PRIORITY_BACKGROUND) + IF_COP(, CPU)); #ifdef DEBUG do diff --git a/apps/plugins/battery_bench.c b/apps/plugins/battery_bench.c index dfe9632f7b..f03a4e2fb7 100644 --- a/apps/plugins/battery_bench.c +++ b/apps/plugins/battery_bench.c @@ -133,8 +133,6 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) return main(); } -bool thread_stopped = false; - /* Struct for battery information */ struct batt_info { @@ -147,6 +145,7 @@ struct batt_info unsigned short flags; } bat[BUF_SIZE/sizeof(struct batt_info)]; +struct thread_entry *thread_id; struct event_queue thread_q; bool exit_tsr(bool reenter) @@ -166,8 +165,7 @@ bool exit_tsr(bool reenter) if (exit) { rb->queue_post(&thread_q, EV_EXIT, 0); - while (!thread_stopped) - rb->yield(); + rb->thread_wait(thread_id); /* remove the thread's queue from the broadcast list */ rb->queue_delete(&thread_q); return true; @@ -350,7 +348,6 @@ void thread(void) #else "bench exit"); #endif - thread_stopped = true; return; } @@ -373,7 +370,6 @@ void thread(void) break; } } while (1); - } @@ -499,10 +495,10 @@ int main(void) } rb->queue_init(&thread_q, true); /* put the thread's queue in the bcast list */ - if(rb->create_thread(thread, thread_stack, + if((thread_id = rb->create_thread(thread, thread_stack, sizeof(thread_stack), 0, "Battery Benchmark" IF_PRIO(, PRIORITY_BACKGROUND) - IF_COP(, CPU)) == NULL) + IF_COP(, CPU))) == NULL) { rb->splash(HZ, "Cannot create thread!"); return PLUGIN_ERROR; diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c index e77031b76e..770abf95ca 100644 --- a/apps/plugins/mpegplayer/mpegplayer.c +++ b/apps/plugins/mpegplayer/mpegplayer.c @@ -188,7 +188,7 @@ typedef struct int have_msg; /* 1=event pending */ int replied; /* 1=replied to last event */ int reply; /* reply value */ - struct spinlock msg_lock; /* serialization for event senders */ + struct mutex msg_lock; /* serialization for event senders */ uint8_t* curr_packet; /* Current stream packet beginning */ uint8_t* curr_packet_end; /* Current stream packet end */ @@ -294,7 +294,7 @@ static intptr_t str_send_msg(Stream *str, int id, intptr_t data) #endif /* Only one thread at a time, please */ - rb->spinlock_lock(&str->msg_lock); + rb->mutex_lock(&str->msg_lock); str->ev.id = id; str->ev.data = data; @@ -316,7 +316,7 @@ static intptr_t str_send_msg(Stream *str, int id, intptr_t data) reply = str->reply; - rb->spinlock_unlock(&str->msg_lock); + rb->mutex_unlock(&str->msg_lock); return reply; } @@ -340,13 +340,13 @@ static size_t file_remaining IBSS_ATTR; #if NUM_CORES > 1 /* Some stream variables are shared between cores */ -struct spinlock stream_lock IBSS_ATTR; +struct mutex stream_lock IBSS_ATTR; static inline void init_stream_lock(void) - { rb->spinlock_init(&stream_lock, SPINLOCK_TASK_SWITCH); } + { rb->mutex_init(&stream_lock); } static inline void lock_stream(void) - { rb->spinlock_lock(&stream_lock); } + { rb->mutex_lock(&stream_lock); } static inline void unlock_stream(void) - { rb->spinlock_unlock(&stream_lock); } + { rb->mutex_unlock(&stream_lock); } #else /* No RMW issue here */ static inline void init_stream_lock(void) @@ -1937,8 +1937,7 @@ void display_thumb(int in_file) } else { - while (video_str.status != STREAM_TERMINATED) - rb->yield(); + rb->thread_wait(video_str.thread); } if ( video_str.curr_packet_end == video_str.curr_packet) @@ -2417,8 +2416,8 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) initialize_stream( &video_str, disk_buf_start, disk_buf_len, 0xe0 ); initialize_stream( &audio_str, disk_buf_start, disk_buf_len, 0xc0 ); - rb->spinlock_init(&audio_str.msg_lock IF_COP(, SPINLOCK_TASK_SWITCH)); - rb->spinlock_init(&video_str.msg_lock IF_COP(, SPINLOCK_TASK_SWITCH)); + rb->mutex_init(&audio_str.msg_lock); + rb->mutex_init(&video_str.msg_lock); audio_str.status = STREAM_BUFFERING; video_str.status = STREAM_PLAYING; @@ -2504,12 +2503,16 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) /* Stop the threads and wait for them to terminate */ if (video_str.thread != NULL) + { str_send_msg(&video_str, STREAM_QUIT, 0); + rb->thread_wait(video_str.thread); + } if (audio_str.thread != NULL) + { str_send_msg(&audio_str, STREAM_QUIT, 0); - - rb->sleep(HZ/10); + rb->thread_wait(audio_str.thread); + } #if NUM_CORES > 1 invalidate_icache(); diff --git a/apps/plugins/test_codec.c b/apps/plugins/test_codec.c index 9859e0c39f..e629e11a79 100644 --- a/apps/plugins/test_codec.c +++ b/apps/plugins/test_codec.c @@ -601,6 +601,9 @@ static enum plugin_status test_track(char* filename) /* Save the current time before we spin up the disk to access the log */ ticks = *rb->current_tick - starttick; + /* Be sure it is done */ + rb->thread_wait(codecthread_id); + log_text(str,true); /* Close WAV file (if there was one) */