summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-10-22 05:57:38 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-10-22 05:57:38 +0000
commit7e12bba0d26a609ce16e981f0ebd4b8e73f59a8e (patch)
tree71673763db2a63da47e34f62e7513b2c8e987c87
parent344c41f644e9b95da55a66ea47d7b4afc6102e47 (diff)
downloadrockbox-7e12bba0d26a609ce16e981f0ebd4b8e73f59a8e.tar.gz
rockbox-7e12bba0d26a609ce16e981f0ebd4b8e73f59a8e.zip
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
-rw-r--r--apps/plugin.c8
-rw-r--r--apps/plugin.h12
-rw-r--r--apps/plugins/alpine_cdc.c13
-rw-r--r--apps/plugins/battery_bench.c12
-rw-r--r--apps/plugins/mpegplayer/mpegplayer.c29
-rw-r--r--apps/plugins/test_codec.c3
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 = {
512 the API gets incompatible */ 512 the API gets incompatible */
513 513
514#if (CONFIG_CODEC == SWCODEC) 514#if (CONFIG_CODEC == SWCODEC)
515 spinlock_init, 515 mutex_init,
516 spinlock_lock, 516 mutex_lock,
517 spinlock_unlock, 517 mutex_unlock,
518#endif 518#endif
519
520 thread_wait,
519}; 521};
520 522
521int plugin_load(const char* plugin, void* parameter) 523int 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 @@
112#define PLUGIN_MAGIC 0x526F634B /* RocK */ 112#define PLUGIN_MAGIC 0x526F634B /* RocK */
113 113
114/* increase this every time the api struct changes */ 114/* increase this every time the api struct changes */
115#define PLUGIN_API_VERSION 85 115#define PLUGIN_API_VERSION 86
116 116
117/* update this to latest version if a change to the api struct breaks 117/* update this to latest version if a change to the api struct breaks
118 backwards compatibility (and please take the opportunity to sort in any 118 backwards compatibility (and please take the opportunity to sort in any
119 new function which are "waiting" at the end of the function table) */ 119 new function which are "waiting" at the end of the function table) */
120#define PLUGIN_MIN_API_VERSION 85 120#define PLUGIN_MIN_API_VERSION 86
121 121
122/* plugin return codes */ 122/* plugin return codes */
123enum plugin_status { 123enum plugin_status {
@@ -634,10 +634,12 @@ struct plugin_api {
634 the API gets incompatible */ 634 the API gets incompatible */
635 635
636#if (CONFIG_CODEC == SWCODEC) 636#if (CONFIG_CODEC == SWCODEC)
637 void (*spinlock_init)(struct spinlock *l IF_COP(, unsigned int flags)); 637 void (*mutex_init)(struct mutex *m);
638 void (*spinlock_lock)(struct spinlock *l); 638 void (*mutex_lock)(struct mutex *m);
639 void (*spinlock_unlock)(struct spinlock *l); 639 void (*mutex_unlock)(struct mutex *m);
640#endif 640#endif
641
642 void (*thread_wait)(struct thread_entry *thread);
641}; 643};
642 644
643/* plugin header */ 645/* 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
204{ 204{
205 bool foreground; /* set as long as we're owning the UI */ 205 bool foreground; /* set as long as we're owning the UI */
206 bool exiting; /* signal to the thread that we want to exit */ 206 bool exiting; /* signal to the thread that we want to exit */
207 bool ended; /* response from the thread, that is has exited */ 207 struct thread_entry *thread; /* worker thread id */
208} gTread; 208} gTread;
209 209
210static struct plugin_api* rb; /* here is the global API struct pointer */ 210static struct plugin_api* rb; /* here is the global API struct pointer */
@@ -1112,8 +1112,6 @@ void thread(void)
1112 } 1112 }
1113 1113
1114 } while (!gTread.exiting); 1114 } while (!gTread.exiting);
1115
1116 gTread.ended = true; /* acknowledge the exit */
1117} 1115}
1118 1116
1119/* callback to end the TSR plugin, called before a new one gets loaded */ 1117/* callback to end the TSR plugin, called before a new one gets loaded */
@@ -1122,8 +1120,7 @@ bool exit_tsr(bool reenter)
1122 if (reenter) 1120 if (reenter)
1123 return false; /* dont let it start again */ 1121 return false; /* dont let it start again */
1124 gTread.exiting = true; /* tell the thread to end */ 1122 gTread.exiting = true; /* tell the thread to end */
1125 while (!gTread.ended) /* wait until it did */ 1123 rb->thread_wait(gTread.thread); /* wait until it did */
1126 rb->yield();
1127 1124
1128 uart_init(BAUDRATE); /* return to standard baudrate */ 1125 uart_init(BAUDRATE); /* return to standard baudrate */
1129 IPRE = (IPRE & ~0xF000); /* UART interrupt off */ 1126 IPRE = (IPRE & ~0xF000); /* UART interrupt off */
@@ -1167,9 +1164,9 @@ int main(void* parameter)
1167 1164
1168 rb->memset(&gTread, 0, sizeof(gTread)); 1165 rb->memset(&gTread, 0, sizeof(gTread));
1169 gTread.foreground = true; 1166 gTread.foreground = true;
1170 rb->create_thread(thread, stack, stacksize, 0, "CDC" 1167 gTread.thread = rb->create_thread(thread, stack, stacksize, 0, "CDC"
1171 IF_PRIO(, PRIORITY_BACKGROUND) 1168 IF_PRIO(, PRIORITY_BACKGROUND)
1172 IF_COP(, CPU)); 1169 IF_COP(, CPU));
1173 1170
1174#ifdef DEBUG 1171#ifdef DEBUG
1175 do 1172 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)
133 return main(); 133 return main();
134} 134}
135 135
136bool thread_stopped = false;
137
138/* Struct for battery information */ 136/* Struct for battery information */
139struct batt_info 137struct batt_info
140{ 138{
@@ -147,6 +145,7 @@ struct batt_info
147 unsigned short flags; 145 unsigned short flags;
148} bat[BUF_SIZE/sizeof(struct batt_info)]; 146} bat[BUF_SIZE/sizeof(struct batt_info)];
149 147
148struct thread_entry *thread_id;
150struct event_queue thread_q; 149struct event_queue thread_q;
151 150
152bool exit_tsr(bool reenter) 151bool exit_tsr(bool reenter)
@@ -166,8 +165,7 @@ bool exit_tsr(bool reenter)
166 if (exit) 165 if (exit)
167 { 166 {
168 rb->queue_post(&thread_q, EV_EXIT, 0); 167 rb->queue_post(&thread_q, EV_EXIT, 0);
169 while (!thread_stopped) 168 rb->thread_wait(thread_id);
170 rb->yield();
171 /* remove the thread's queue from the broadcast list */ 169 /* remove the thread's queue from the broadcast list */
172 rb->queue_delete(&thread_q); 170 rb->queue_delete(&thread_q);
173 return true; 171 return true;
@@ -350,7 +348,6 @@ void thread(void)
350#else 348#else
351 "bench exit"); 349 "bench exit");
352#endif 350#endif
353 thread_stopped = true;
354 return; 351 return;
355 } 352 }
356 353
@@ -373,7 +370,6 @@ void thread(void)
373 break; 370 break;
374 } 371 }
375 } while (1); 372 } while (1);
376
377} 373}
378 374
379 375
@@ -499,10 +495,10 @@ int main(void)
499 } 495 }
500 496
501 rb->queue_init(&thread_q, true); /* put the thread's queue in the bcast list */ 497 rb->queue_init(&thread_q, true); /* put the thread's queue in the bcast list */
502 if(rb->create_thread(thread, thread_stack, 498 if((thread_id = rb->create_thread(thread, thread_stack,
503 sizeof(thread_stack), 0, "Battery Benchmark" 499 sizeof(thread_stack), 0, "Battery Benchmark"
504 IF_PRIO(, PRIORITY_BACKGROUND) 500 IF_PRIO(, PRIORITY_BACKGROUND)
505 IF_COP(, CPU)) == NULL) 501 IF_COP(, CPU))) == NULL)
506 { 502 {
507 rb->splash(HZ, "Cannot create thread!"); 503 rb->splash(HZ, "Cannot create thread!");
508 return PLUGIN_ERROR; 504 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
188 int have_msg; /* 1=event pending */ 188 int have_msg; /* 1=event pending */
189 int replied; /* 1=replied to last event */ 189 int replied; /* 1=replied to last event */
190 int reply; /* reply value */ 190 int reply; /* reply value */
191 struct spinlock msg_lock; /* serialization for event senders */ 191 struct mutex msg_lock; /* serialization for event senders */
192 uint8_t* curr_packet; /* Current stream packet beginning */ 192 uint8_t* curr_packet; /* Current stream packet beginning */
193 uint8_t* curr_packet_end; /* Current stream packet end */ 193 uint8_t* curr_packet_end; /* Current stream packet end */
194 194
@@ -294,7 +294,7 @@ static intptr_t str_send_msg(Stream *str, int id, intptr_t data)
294#endif 294#endif
295 295
296 /* Only one thread at a time, please */ 296 /* Only one thread at a time, please */
297 rb->spinlock_lock(&str->msg_lock); 297 rb->mutex_lock(&str->msg_lock);
298 298
299 str->ev.id = id; 299 str->ev.id = id;
300 str->ev.data = data; 300 str->ev.data = data;
@@ -316,7 +316,7 @@ static intptr_t str_send_msg(Stream *str, int id, intptr_t data)
316 316
317 reply = str->reply; 317 reply = str->reply;
318 318
319 rb->spinlock_unlock(&str->msg_lock); 319 rb->mutex_unlock(&str->msg_lock);
320 320
321 return reply; 321 return reply;
322} 322}
@@ -340,13 +340,13 @@ static size_t file_remaining IBSS_ATTR;
340 340
341#if NUM_CORES > 1 341#if NUM_CORES > 1
342/* Some stream variables are shared between cores */ 342/* Some stream variables are shared between cores */
343struct spinlock stream_lock IBSS_ATTR; 343struct mutex stream_lock IBSS_ATTR;
344static inline void init_stream_lock(void) 344static inline void init_stream_lock(void)
345 { rb->spinlock_init(&stream_lock, SPINLOCK_TASK_SWITCH); } 345 { rb->mutex_init(&stream_lock); }
346static inline void lock_stream(void) 346static inline void lock_stream(void)
347 { rb->spinlock_lock(&stream_lock); } 347 { rb->mutex_lock(&stream_lock); }
348static inline void unlock_stream(void) 348static inline void unlock_stream(void)
349 { rb->spinlock_unlock(&stream_lock); } 349 { rb->mutex_unlock(&stream_lock); }
350#else 350#else
351/* No RMW issue here */ 351/* No RMW issue here */
352static inline void init_stream_lock(void) 352static inline void init_stream_lock(void)
@@ -1937,8 +1937,7 @@ void display_thumb(int in_file)
1937 } 1937 }
1938 else 1938 else
1939 { 1939 {
1940 while (video_str.status != STREAM_TERMINATED) 1940 rb->thread_wait(video_str.thread);
1941 rb->yield();
1942 } 1941 }
1943 1942
1944 if ( video_str.curr_packet_end == video_str.curr_packet) 1943 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)
2417 initialize_stream( &video_str, disk_buf_start, disk_buf_len, 0xe0 ); 2416 initialize_stream( &video_str, disk_buf_start, disk_buf_len, 0xe0 );
2418 initialize_stream( &audio_str, disk_buf_start, disk_buf_len, 0xc0 ); 2417 initialize_stream( &audio_str, disk_buf_start, disk_buf_len, 0xc0 );
2419 2418
2420 rb->spinlock_init(&audio_str.msg_lock IF_COP(, SPINLOCK_TASK_SWITCH)); 2419 rb->mutex_init(&audio_str.msg_lock);
2421 rb->spinlock_init(&video_str.msg_lock IF_COP(, SPINLOCK_TASK_SWITCH)); 2420 rb->mutex_init(&video_str.msg_lock);
2422 2421
2423 audio_str.status = STREAM_BUFFERING; 2422 audio_str.status = STREAM_BUFFERING;
2424 video_str.status = STREAM_PLAYING; 2423 video_str.status = STREAM_PLAYING;
@@ -2504,12 +2503,16 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
2504 2503
2505 /* Stop the threads and wait for them to terminate */ 2504 /* Stop the threads and wait for them to terminate */
2506 if (video_str.thread != NULL) 2505 if (video_str.thread != NULL)
2506 {
2507 str_send_msg(&video_str, STREAM_QUIT, 0); 2507 str_send_msg(&video_str, STREAM_QUIT, 0);
2508 rb->thread_wait(video_str.thread);
2509 }
2508 2510
2509 if (audio_str.thread != NULL) 2511 if (audio_str.thread != NULL)
2512 {
2510 str_send_msg(&audio_str, STREAM_QUIT, 0); 2513 str_send_msg(&audio_str, STREAM_QUIT, 0);
2511 2514 rb->thread_wait(audio_str.thread);
2512 rb->sleep(HZ/10); 2515 }
2513 2516
2514#if NUM_CORES > 1 2517#if NUM_CORES > 1
2515 invalidate_icache(); 2518 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)
601 /* Save the current time before we spin up the disk to access the log */ 601 /* Save the current time before we spin up the disk to access the log */
602 ticks = *rb->current_tick - starttick; 602 ticks = *rb->current_tick - starttick;
603 603
604 /* Be sure it is done */
605 rb->thread_wait(codecthread_id);
606
604 log_text(str,true); 607 log_text(str,true);
605 608
606 /* Close WAV file (if there was one) */ 609 /* Close WAV file (if there was one) */