summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2008-12-10 08:57:10 +0000
committerMichael Sevakis <jethead71@rockbox.org>2008-12-10 08:57:10 +0000
commit8cfbd3604fac14f629244e521ad24ffa9938c790 (patch)
tree16dc096519b8b537bb7d4b73e0c97f5f33ee752b
parent40ff47c7eea41ac893d7af5c5b97ace52a5ffade (diff)
downloadrockbox-8cfbd3604fac14f629244e521ad24ffa9938c790.tar.gz
rockbox-8cfbd3604fac14f629244e521ad24ffa9938c790.zip
Use cookies for thread identification instead of pointers directly which gives a buffer against wrongly identifying a thread when the slot is recycled (which has been nagging me for awhile). A slot gets 255 uses before it repeats. Everything gets incompatible so a full update is required.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19377 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/buffering.c8
-rw-r--r--apps/codecs.h10
-rw-r--r--apps/codecs/mpa.c8
-rw-r--r--apps/codecs/spc.c12
-rw-r--r--apps/pcmbuf.c8
-rw-r--r--apps/playback.c16
-rw-r--r--apps/plugin.c6
-rw-r--r--apps/plugin.h26
-rw-r--r--apps/plugins/alpine_cdc.c2
-rw-r--r--apps/plugins/battery_bench.c4
-rw-r--r--apps/plugins/mpegplayer/audio_thread.c6
-rw-r--r--apps/plugins/mpegplayer/disk_buf.c8
-rw-r--r--apps/plugins/mpegplayer/disk_buf.h2
-rw-r--r--apps/plugins/mpegplayer/mpeg_parser.c2
-rw-r--r--apps/plugins/mpegplayer/stream_mgr.c20
-rw-r--r--apps/plugins/mpegplayer/stream_mgr.h2
-rw-r--r--apps/plugins/mpegplayer/stream_thread.h2
-rw-r--r--apps/plugins/mpegplayer/video_thread.c6
-rw-r--r--apps/plugins/pictureflow.c4
-rw-r--r--apps/plugins/test_codec.c4
-rw-r--r--apps/plugins/test_sampr.c14
-rw-r--r--apps/recorder/pcm_record.c20
-rw-r--r--apps/voice_thread.c10
-rw-r--r--firmware/backlight.c10
-rw-r--r--firmware/drivers/ata.c15
-rw-r--r--firmware/export/kernel.h2
-rw-r--r--firmware/export/thread.h38
-rw-r--r--firmware/kernel.c23
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c12
-rw-r--r--firmware/thread.c140
-rw-r--r--firmware/usb.c8
-rw-r--r--uisimulator/sdl/thread-sdl.c115
32 files changed, 329 insertions, 234 deletions
diff --git a/apps/buffering.c b/apps/buffering.c
index dfc90065d6..6160869498 100644
--- a/apps/buffering.c
+++ b/apps/buffering.c
@@ -184,7 +184,7 @@ enum {
184static void buffering_thread(void); 184static void buffering_thread(void);
185static long buffering_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)]; 185static long buffering_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)];
186static const char buffering_thread_name[] = "buffering"; 186static const char buffering_thread_name[] = "buffering";
187static struct thread_entry *buffering_thread_p; 187static unsigned int buffering_thread_id = 0;
188static struct event_queue buffering_queue; 188static struct event_queue buffering_queue;
189static struct queue_sender_list buffering_queue_sender_list; 189static struct queue_sender_list buffering_queue_sender_list;
190 190
@@ -1468,13 +1468,13 @@ void buffering_init(void)
1468 conf_watermark = BUFFERING_DEFAULT_WATERMARK; 1468 conf_watermark = BUFFERING_DEFAULT_WATERMARK;
1469 1469
1470 queue_init(&buffering_queue, true); 1470 queue_init(&buffering_queue, true);
1471 buffering_thread_p = create_thread( buffering_thread, buffering_stack, 1471 buffering_thread_id = create_thread( buffering_thread, buffering_stack,
1472 sizeof(buffering_stack), CREATE_THREAD_FROZEN, 1472 sizeof(buffering_stack), CREATE_THREAD_FROZEN,
1473 buffering_thread_name IF_PRIO(, PRIORITY_BUFFERING) 1473 buffering_thread_name IF_PRIO(, PRIORITY_BUFFERING)
1474 IF_COP(, CPU)); 1474 IF_COP(, CPU));
1475 1475
1476 queue_enable_queue_send(&buffering_queue, &buffering_queue_sender_list, 1476 queue_enable_queue_send(&buffering_queue, &buffering_queue_sender_list,
1477 buffering_thread_p); 1477 buffering_thread_id);
1478} 1478}
1479 1479
1480/* Initialise the buffering subsystem */ 1480/* Initialise the buffering subsystem */
@@ -1501,7 +1501,7 @@ bool buffering_reset(char *buf, size_t buflen)
1501 high_watermark = 3*buflen / 4; 1501 high_watermark = 3*buflen / 4;
1502#endif 1502#endif
1503 1503
1504 thread_thaw(buffering_thread_p); 1504 thread_thaw(buffering_thread_id);
1505 1505
1506 return true; 1506 return true;
1507} 1507}
diff --git a/apps/codecs.h b/apps/codecs.h
index 4194524e6d..d765daba2a 100644
--- a/apps/codecs.h
+++ b/apps/codecs.h
@@ -82,12 +82,12 @@
82#define CODEC_ENC_MAGIC 0x52454E43 /* RENC */ 82#define CODEC_ENC_MAGIC 0x52454E43 /* RENC */
83 83
84/* increase this every time the api struct changes */ 84/* increase this every time the api struct changes */
85#define CODEC_API_VERSION 27 85#define CODEC_API_VERSION 28
86 86
87/* update this to latest version if a change to the api struct breaks 87/* update this to latest version if a change to the api struct breaks
88 backwards compatibility (and please take the opportunity to sort in any 88 backwards compatibility (and please take the opportunity to sort in any
89 new function which are "waiting" at the end of the function table) */ 89 new function which are "waiting" at the end of the function table) */
90#define CODEC_MIN_API_VERSION 27 90#define CODEC_MIN_API_VERSION 28
91 91
92/* codec return codes */ 92/* codec return codes */
93enum codec_status { 93enum codec_status {
@@ -164,14 +164,14 @@ struct codec_api {
164 void (*yield)(void); 164 void (*yield)(void);
165 165
166#if NUM_CORES > 1 166#if NUM_CORES > 1
167 struct thread_entry * 167 unsigned int
168 (*create_thread)(void (*function)(void), void* stack, 168 (*create_thread)(void (*function)(void), void* stack,
169 size_t stack_size, unsigned flags, const char *name 169 size_t stack_size, unsigned flags, const char *name
170 IF_PRIO(, int priority) 170 IF_PRIO(, int priority)
171 IF_COP(, unsigned int core)); 171 IF_COP(, unsigned int core));
172 172
173 void (*thread_thaw)(struct thread_entry *thread); 173 void (*thread_thaw)(unsigned int thread_id);
174 void (*thread_wait)(struct thread_entry *thread); 174 void (*thread_wait)(unsigned int thread_id);
175 void (*semaphore_init)(struct semaphore *s, int max, int start); 175 void (*semaphore_init)(struct semaphore *s, int max, int start);
176 void (*semaphore_wait)(struct semaphore *s); 176 void (*semaphore_wait)(struct semaphore *s);
177 void (*semaphore_release)(struct semaphore *s); 177 void (*semaphore_release)(struct semaphore *s);
diff --git a/apps/codecs/mpa.c b/apps/codecs/mpa.c
index 7732622383..37a1afadfa 100644
--- a/apps/codecs/mpa.c
+++ b/apps/codecs/mpa.c
@@ -200,7 +200,7 @@ static void set_elapsed(struct mp3entry* id3)
200static int mad_synth_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)/2] IBSS_ATTR; 200static int mad_synth_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)/2] IBSS_ATTR;
201 201
202static const unsigned char * const mad_synth_thread_name = "mp3dec"; 202static const unsigned char * const mad_synth_thread_name = "mp3dec";
203static struct thread_entry *mad_synth_thread_p; 203static unsigned int mad_synth_thread_id = 0;
204 204
205 205
206static void mad_synth_thread(void) 206static void mad_synth_thread(void)
@@ -249,14 +249,14 @@ static bool mad_synth_thread_create(void)
249 ci->semaphore_init(&synth_done_sem, 1, 0); 249 ci->semaphore_init(&synth_done_sem, 1, 0);
250 ci->semaphore_init(&synth_pending_sem, 1, 0); 250 ci->semaphore_init(&synth_pending_sem, 1, 0);
251 251
252 mad_synth_thread_p = ci->create_thread(mad_synth_thread, 252 mad_synth_thread_id = ci->create_thread(mad_synth_thread,
253 mad_synth_thread_stack, 253 mad_synth_thread_stack,
254 sizeof(mad_synth_thread_stack), 0, 254 sizeof(mad_synth_thread_stack), 0,
255 mad_synth_thread_name 255 mad_synth_thread_name
256 IF_PRIO(, PRIORITY_PLAYBACK) 256 IF_PRIO(, PRIORITY_PLAYBACK)
257 IF_COP(, COP)); 257 IF_COP(, COP));
258 258
259 if (mad_synth_thread_p == NULL) 259 if (mad_synth_thread_id == 0)
260 return false; 260 return false;
261 261
262 return true; 262 return true;
@@ -267,7 +267,7 @@ static void mad_synth_thread_quit(void)
267 /*mop up COP thread*/ 267 /*mop up COP thread*/
268 die=1; 268 die=1;
269 ci->semaphore_release(&synth_pending_sem); 269 ci->semaphore_release(&synth_pending_sem);
270 ci->thread_wait(mad_synth_thread_p); 270 ci->thread_wait(mad_synth_thread_id);
271 invalidate_icache(); 271 invalidate_icache();
272} 272}
273#else 273#else
diff --git a/apps/codecs/spc.c b/apps/codecs/spc.c
index 380cfbdb8b..14d28dfca8 100644
--- a/apps/codecs/spc.c
+++ b/apps/codecs/spc.c
@@ -197,7 +197,7 @@ static int spc_emu_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)]
197 CACHEALIGN_ATTR; 197 CACHEALIGN_ATTR;
198 198
199static const unsigned char * const spc_emu_thread_name = "spc emu"; 199static const unsigned char * const spc_emu_thread_name = "spc emu";
200static struct thread_entry *emu_thread_p; 200static unsigned int emu_thread_id = 0;
201 201
202enum 202enum
203{ 203{
@@ -352,11 +352,11 @@ static void spc_emu_thread(void)
352 352
353static bool spc_emu_start(void) 353static bool spc_emu_start(void)
354{ 354{
355 emu_thread_p = ci->create_thread(spc_emu_thread, spc_emu_thread_stack, 355 emu_thread_id = ci->create_thread(spc_emu_thread, spc_emu_thread_stack,
356 sizeof(spc_emu_thread_stack), CREATE_THREAD_FROZEN, 356 sizeof(spc_emu_thread_stack), CREATE_THREAD_FROZEN,
357 spc_emu_thread_name IF_PRIO(, PRIORITY_PLAYBACK), COP); 357 spc_emu_thread_name IF_PRIO(, PRIORITY_PLAYBACK), COP);
358 358
359 if (emu_thread_p == NULL) 359 if (emu_thread_id == 0)
360 return false; 360 return false;
361 361
362 /* Initialize audio queue as full to prevent emu thread from trying to run the 362 /* Initialize audio queue as full to prevent emu thread from trying to run the
@@ -368,7 +368,7 @@ static bool spc_emu_start(void)
368 sample_queue.tail = 2; 368 sample_queue.tail = 2;
369 369
370 /* Start it running */ 370 /* Start it running */
371 ci->thread_thaw(emu_thread_p); 371 ci->thread_thaw(emu_thread_id);
372 return true; 372 return true;
373} 373}
374 374
@@ -382,10 +382,10 @@ static inline int load_spc_buffer(uint8_t *buf, size_t size)
382 382
383static inline void spc_emu_quit(void) 383static inline void spc_emu_quit(void)
384{ 384{
385 if (emu_thread_p != NULL) { 385 if (emu_thread_id != 0) {
386 emu_thread_send_msg(SPC_EMU_QUIT, 0); 386 emu_thread_send_msg(SPC_EMU_QUIT, 0);
387 /* Wait for emu thread to be killed */ 387 /* Wait for emu thread to be killed */
388 ci->thread_wait(emu_thread_p); 388 ci->thread_wait(emu_thread_id);
389 invalidate_icache(); 389 invalidate_icache();
390 } 390 }
391} 391}
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index c7db4d3101..9ca5fbf5cf 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -115,7 +115,7 @@ static bool pcmbuf_flush;
115static int codec_thread_priority = PRIORITY_PLAYBACK; 115static int codec_thread_priority = PRIORITY_PLAYBACK;
116#endif 116#endif
117 117
118extern struct thread_entry *codec_thread_p; 118extern uintptr_t codec_thread_id;
119 119
120/* Helpful macros for use in conditionals this assumes some of the above 120/* Helpful macros for use in conditionals this assumes some of the above
121 * static variable names */ 121 * static variable names */
@@ -258,13 +258,13 @@ static void boost_codec_thread(bool boost)
258 if (priority != codec_thread_priority) 258 if (priority != codec_thread_priority)
259 { 259 {
260 codec_thread_priority = priority; 260 codec_thread_priority = priority;
261 thread_set_priority(codec_thread_p, priority); 261 thread_set_priority(codec_thread_id, priority);
262 voice_thread_set_priority(priority); 262 voice_thread_set_priority(priority);
263 } 263 }
264 } 264 }
265 else if (codec_thread_priority != PRIORITY_PLAYBACK) 265 else if (codec_thread_priority != PRIORITY_PLAYBACK)
266 { 266 {
267 thread_set_priority(codec_thread_p, PRIORITY_PLAYBACK); 267 thread_set_priority(codec_thread_id, PRIORITY_PLAYBACK);
268 voice_thread_set_priority(PRIORITY_PLAYBACK); 268 voice_thread_set_priority(PRIORITY_PLAYBACK);
269 codec_thread_priority = PRIORITY_PLAYBACK; 269 codec_thread_priority = PRIORITY_PLAYBACK;
270 } 270 }
@@ -276,7 +276,7 @@ static void pcmbuf_under_watermark(void)
276 /* Only codec thread initiates boost - voice boosts the cpu when playing 276 /* Only codec thread initiates boost - voice boosts the cpu when playing
277 a clip */ 277 a clip */
278#ifndef SIMULATOR 278#ifndef SIMULATOR
279 if (thread_get_current() == codec_thread_p) 279 if (thread_get_current() == codec_thread_id)
280#endif /* SIMULATOR */ 280#endif /* SIMULATOR */
281 { 281 {
282#ifdef HAVE_PRIORITY_SCHEDULING 282#ifdef HAVE_PRIORITY_SCHEDULING
diff --git a/apps/playback.c b/apps/playback.c
index 50c4017200..3aed12e918 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -299,7 +299,7 @@ static struct queue_sender_list codec_queue_sender_list;
299static long codec_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)] 299static long codec_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)]
300IBSS_ATTR; 300IBSS_ATTR;
301static const char codec_thread_name[] = "codec"; 301static const char codec_thread_name[] = "codec";
302struct thread_entry *codec_thread_p; /* For modifying thread priority later. */ 302unsigned int codec_thread_id; /* For modifying thread priority later. */
303 303
304/* PCM buffer messaging */ 304/* PCM buffer messaging */
305static struct event_queue pcmbuf_queue SHAREDBSS_ATTR; 305static struct event_queue pcmbuf_queue SHAREDBSS_ATTR;
@@ -2499,7 +2499,7 @@ static void audio_thread(void)
2499 */ 2499 */
2500void audio_init(void) 2500void audio_init(void)
2501{ 2501{
2502 struct thread_entry *audio_thread_p; 2502 unsigned int audio_thread_id;
2503 2503
2504 /* Can never do this twice */ 2504 /* Can never do this twice */
2505 if (audio_is_initialized) 2505 if (audio_is_initialized)
@@ -2543,22 +2543,22 @@ void audio_init(void)
2543 talk first */ 2543 talk first */
2544 talk_init(); 2544 talk_init();
2545 2545
2546 codec_thread_p = create_thread( 2546 codec_thread_id = create_thread(
2547 codec_thread, codec_stack, sizeof(codec_stack), 2547 codec_thread, codec_stack, sizeof(codec_stack),
2548 CREATE_THREAD_FROZEN, 2548 CREATE_THREAD_FROZEN,
2549 codec_thread_name IF_PRIO(, PRIORITY_PLAYBACK) 2549 codec_thread_name IF_PRIO(, PRIORITY_PLAYBACK)
2550 IF_COP(, CPU)); 2550 IF_COP(, CPU));
2551 2551
2552 queue_enable_queue_send(&codec_queue, &codec_queue_sender_list, 2552 queue_enable_queue_send(&codec_queue, &codec_queue_sender_list,
2553 codec_thread_p); 2553 codec_thread_id);
2554 2554
2555 audio_thread_p = create_thread(audio_thread, audio_stack, 2555 audio_thread_id = create_thread(audio_thread, audio_stack,
2556 sizeof(audio_stack), CREATE_THREAD_FROZEN, 2556 sizeof(audio_stack), CREATE_THREAD_FROZEN,
2557 audio_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) 2557 audio_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
2558 IF_COP(, CPU)); 2558 IF_COP(, CPU));
2559 2559
2560 queue_enable_queue_send(&audio_queue, &audio_queue_sender_list, 2560 queue_enable_queue_send(&audio_queue, &audio_queue_sender_list,
2561 audio_thread_p); 2561 audio_thread_id);
2562 2562
2563#ifdef PLAYBACK_VOICE 2563#ifdef PLAYBACK_VOICE
2564 voice_thread_init(); 2564 voice_thread_init();
@@ -2599,8 +2599,8 @@ void audio_init(void)
2599#ifdef PLAYBACK_VOICE 2599#ifdef PLAYBACK_VOICE
2600 voice_thread_resume(); 2600 voice_thread_resume();
2601#endif 2601#endif
2602 thread_thaw(codec_thread_p); 2602 thread_thaw(codec_thread_id);
2603 thread_thaw(audio_thread_p); 2603 thread_thaw(audio_thread_id);
2604 2604
2605} /* audio_init */ 2605} /* audio_init */
2606 2606
diff --git a/apps/plugin.c b/apps/plugin.c
index de2dd3f7c7..e55ecd46a7 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -146,7 +146,8 @@ static const struct plugin_api rockbox_api = {
146 font_get_width, 146 font_get_width,
147 screen_clear_area, 147 screen_clear_area,
148 gui_scrollbar_draw, 148 gui_scrollbar_draw,
149#endif 149#endif /* HAVE_LCD_BITMAP */
150 get_codepage_name,
150 151
151 backlight_on, 152 backlight_on,
152 backlight_off, 153 backlight_off,
@@ -482,6 +483,7 @@ static const struct plugin_api rockbox_api = {
482 &statusbars, 483 &statusbars,
483 gui_syncstatusbar_draw, 484 gui_syncstatusbar_draw,
484 /* options */ 485 /* options */
486 get_settings_list,
485 find_setting, 487 find_setting,
486 option_screen, 488 option_screen,
487 set_option, 489 set_option,
@@ -619,8 +621,6 @@ static const struct plugin_api rockbox_api = {
619 appsversion, 621 appsversion,
620 /* new stuff at the end, sort into place next time 622 /* new stuff at the end, sort into place next time
621 the API gets incompatible */ 623 the API gets incompatible */
622 get_settings_list,
623 get_codepage_name,
624}; 624};
625 625
626int plugin_load(const char* plugin, const void* parameter) 626int plugin_load(const char* plugin, const void* parameter)
diff --git a/apps/plugin.h b/apps/plugin.h
index fd01e15bbd..e91c866098 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -7,7 +7,7 @@
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2002 Björn Stenberg 10 * Copyright (C) 2002 Björn Stenberg
11 * 11 *
12 * This program is free software; you can redistribute it and/or 12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 13 * modify it under the terms of the GNU General Public License
@@ -131,12 +131,12 @@ void* plugin_get_buffer(size_t *buffer_size);
131#define PLUGIN_MAGIC 0x526F634B /* RocK */ 131#define PLUGIN_MAGIC 0x526F634B /* RocK */
132 132
133/* increase this every time the api struct changes */ 133/* increase this every time the api struct changes */
134#define PLUGIN_API_VERSION 128 134#define PLUGIN_API_VERSION 129
135 135
136/* update this to latest version if a change to the api struct breaks 136/* update this to latest version if a change to the api struct breaks
137 backwards compatibility (and please take the opportunity to sort in any 137 backwards compatibility (and please take the opportunity to sort in any
138 new function which are "waiting" at the end of the function table) */ 138 new function which are "waiting" at the end of the function table) */
139#define PLUGIN_MIN_API_VERSION 127 139#define PLUGIN_MIN_API_VERSION 129
140 140
141/* plugin return codes */ 141/* plugin return codes */
142enum plugin_status { 142enum plugin_status {
@@ -244,6 +244,7 @@ struct plugin_api {
244 int min_shown, int max_shown, 244 int min_shown, int max_shown,
245 unsigned flags); 245 unsigned flags);
246#endif /* HAVE_LCD_BITMAP */ 246#endif /* HAVE_LCD_BITMAP */
247 const char* (*get_codepage_name)(int cp);
247 248
248 /* backlight */ 249 /* backlight */
249 /* The backlight_* functions must be present in the API regardless whether 250 /* The backlight_* functions must be present in the API regardless whether
@@ -408,13 +409,13 @@ struct plugin_api {
408 long (*default_event_handler)(long event); 409 long (*default_event_handler)(long event);
409 long (*default_event_handler_ex)(long event, void (*callback)(void *), void *parameter); 410 long (*default_event_handler_ex)(long event, void (*callback)(void *), void *parameter);
410 struct thread_entry* threads; 411 struct thread_entry* threads;
411 struct thread_entry* (*create_thread)(void (*function)(void), void* stack, 412 unsigned int (*create_thread)(void (*function)(void), void* stack,
412 size_t stack_size, unsigned flags, 413 size_t stack_size, unsigned flags,
413 const char *name 414 const char *name
414 IF_PRIO(, int priority) 415 IF_PRIO(, int priority)
415 IF_COP(, unsigned int core)); 416 IF_COP(, unsigned int core));
416 void (*thread_exit)(void); 417 void (*thread_exit)(void);
417 void (*thread_wait)(struct thread_entry *thread); 418 void (*thread_wait)(unsigned int thread_id);
418#if CONFIG_CODEC == SWCODEC 419#if CONFIG_CODEC == SWCODEC
419 void (*mutex_init)(struct mutex *m); 420 void (*mutex_init)(struct mutex *m);
420 void (*mutex_lock)(struct mutex *m); 421 void (*mutex_lock)(struct mutex *m);
@@ -456,7 +457,7 @@ struct plugin_api {
456#if CONFIG_CODEC == SWCODEC 457#if CONFIG_CODEC == SWCODEC
457 void (*queue_enable_queue_send)(struct event_queue *q, 458 void (*queue_enable_queue_send)(struct event_queue *q,
458 struct queue_sender_list *send, 459 struct queue_sender_list *send,
459 struct thread_entry *owner); 460 unsigned int thread_id);
460 bool (*queue_empty)(const struct event_queue *q); 461 bool (*queue_empty)(const struct event_queue *q);
461 void (*queue_wait)(struct event_queue *q, struct queue_event *ev); 462 void (*queue_wait)(struct event_queue *q, struct queue_event *ev);
462 intptr_t (*queue_send)(struct event_queue *q, long id, 463 intptr_t (*queue_send)(struct event_queue *q, long id,
@@ -616,6 +617,7 @@ struct plugin_api {
616 void (*gui_syncstatusbar_draw)(struct gui_syncstatusbar * bars, bool force_redraw); 617 void (*gui_syncstatusbar_draw)(struct gui_syncstatusbar * bars, bool force_redraw);
617 618
618 /* options */ 619 /* options */
620 const struct settings_list* (*get_settings_list)(int*count);
619 const struct settings_list* (*find_setting)(const void* variable, int *id); 621 const struct settings_list* (*find_setting)(const void* variable, int *id);
620 bool (*option_screen)(const struct settings_list *setting, 622 bool (*option_screen)(const struct settings_list *setting,
621 struct viewport parent[NB_SCREENS], 623 struct viewport parent[NB_SCREENS],
@@ -771,7 +773,7 @@ struct plugin_api {
771 char *buf, int buflen); 773 char *buf, int buflen);
772#endif 774#endif
773 775
774 void (*thread_thaw)(struct thread_entry *thread); 776 void (*thread_thaw)(unsigned int thread_id);
775 777
776#ifdef HAVE_SEMAPHORE_OBJECTS 778#ifdef HAVE_SEMAPHORE_OBJECTS
777 void (*semaphore_init)(struct semaphore *s, int max, int start); 779 void (*semaphore_init)(struct semaphore *s, int max, int start);
@@ -782,8 +784,6 @@ struct plugin_api {
782 const char *appsversion; 784 const char *appsversion;
783 /* new stuff at the end, sort into place next time 785 /* new stuff at the end, sort into place next time
784 the API gets incompatible */ 786 the API gets incompatible */
785 const struct settings_list* (*get_settings_list)(int*count);
786 const char* (*get_codepage_name)(int cp);
787}; 787};
788 788
789/* plugin header */ 789/* plugin header */
diff --git a/apps/plugins/alpine_cdc.c b/apps/plugins/alpine_cdc.c
index dfffc3b3cd..d15e26ae36 100644
--- a/apps/plugins/alpine_cdc.c
+++ b/apps/plugins/alpine_cdc.c
@@ -206,7 +206,7 @@ struct
206{ 206{
207 bool foreground; /* set as long as we're owning the UI */ 207 bool foreground; /* set as long as we're owning the UI */
208 bool exiting; /* signal to the thread that we want to exit */ 208 bool exiting; /* signal to the thread that we want to exit */
209 struct thread_entry *thread; /* worker thread id */ 209 unsigned int thread; /* worker thread id */
210} gTread; 210} gTread;
211 211
212static const struct plugin_api* rb; /* here is the global API struct pointer */ 212static const struct plugin_api* rb; /* here is the global API struct pointer */
diff --git a/apps/plugins/battery_bench.c b/apps/plugins/battery_bench.c
index b951b01432..0c30ebabc3 100644
--- a/apps/plugins/battery_bench.c
+++ b/apps/plugins/battery_bench.c
@@ -216,7 +216,7 @@ struct batt_info
216 216
217#define BUF_ELEMENTS (sizeof(bat)/sizeof(struct batt_info)) 217#define BUF_ELEMENTS (sizeof(bat)/sizeof(struct batt_info))
218 218
219static struct thread_entry *thread_id; 219static unsigned int thread_id;
220static struct event_queue thread_q; 220static struct event_queue thread_q;
221static bool in_usb_mode; 221static bool in_usb_mode;
222static unsigned int buf_idx; 222static unsigned int buf_idx;
@@ -537,7 +537,7 @@ int main(void)
537 if ((thread_id = rb->create_thread(thread, thread_stack, 537 if ((thread_id = rb->create_thread(thread, thread_stack,
538 sizeof(thread_stack), 0, "Battery Benchmark" 538 sizeof(thread_stack), 0, "Battery Benchmark"
539 IF_PRIO(, PRIORITY_BACKGROUND) 539 IF_PRIO(, PRIORITY_BACKGROUND)
540 IF_COP(, CPU))) == NULL) 540 IF_COP(, CPU))) == 0)
541 { 541 {
542 rb->splash(HZ, "Cannot create thread!"); 542 rb->splash(HZ, "Cannot create thread!");
543 return PLUGIN_ERROR; 543 return PLUGIN_ERROR;
diff --git a/apps/plugins/mpegplayer/audio_thread.c b/apps/plugins/mpegplayer/audio_thread.c
index 45226575c9..2fb46efd56 100644
--- a/apps/plugins/mpegplayer/audio_thread.c
+++ b/apps/plugins/mpegplayer/audio_thread.c
@@ -732,7 +732,7 @@ bool audio_thread_init(void)
732 rb->queue_enable_queue_send(audio_str.hdr.q, &audio_str_queue_send, 732 rb->queue_enable_queue_send(audio_str.hdr.q, &audio_str_queue_send,
733 audio_str.thread); 733 audio_str.thread);
734 734
735 if (audio_str.thread == NULL) 735 if (audio_str.thread == 0)
736 return false; 736 return false;
737 737
738 /* Wait for thread to initialize */ 738 /* Wait for thread to initialize */
@@ -744,11 +744,11 @@ bool audio_thread_init(void)
744/* Stops the audio thread */ 744/* Stops the audio thread */
745void audio_thread_exit(void) 745void audio_thread_exit(void)
746{ 746{
747 if (audio_str.thread != NULL) 747 if (audio_str.thread != 0)
748 { 748 {
749 str_post_msg(&audio_str, STREAM_QUIT, 0); 749 str_post_msg(&audio_str, STREAM_QUIT, 0);
750 rb->thread_wait(audio_str.thread); 750 rb->thread_wait(audio_str.thread);
751 audio_str.thread = NULL; 751 audio_str.thread = 0;
752 } 752 }
753 753
754#ifndef SIMULATOR 754#ifndef SIMULATOR
diff --git a/apps/plugins/mpegplayer/disk_buf.c b/apps/plugins/mpegplayer/disk_buf.c
index df5e005b50..c008139356 100644
--- a/apps/plugins/mpegplayer/disk_buf.c
+++ b/apps/plugins/mpegplayer/disk_buf.c
@@ -835,7 +835,7 @@ void disk_buf_reply_msg(intptr_t retval)
835 835
836bool disk_buf_init(void) 836bool disk_buf_init(void)
837{ 837{
838 disk_buf.thread = NULL; 838 disk_buf.thread = 0;
839 list_initialize(&nf_list); 839 list_initialize(&nf_list);
840 840
841 rb->mutex_init(&disk_buf_mtx); 841 rb->mutex_init(&disk_buf_mtx);
@@ -893,7 +893,7 @@ bool disk_buf_init(void)
893 rb->queue_enable_queue_send(disk_buf.q, &disk_buf_queue_send, 893 rb->queue_enable_queue_send(disk_buf.q, &disk_buf_queue_send,
894 disk_buf.thread); 894 disk_buf.thread);
895 895
896 if (disk_buf.thread == NULL) 896 if (disk_buf.thread == 0)
897 return false; 897 return false;
898 898
899 /* Wait for thread to initialize */ 899 /* Wait for thread to initialize */
@@ -904,10 +904,10 @@ bool disk_buf_init(void)
904 904
905void disk_buf_exit(void) 905void disk_buf_exit(void)
906{ 906{
907 if (disk_buf.thread != NULL) 907 if (disk_buf.thread != 0)
908 { 908 {
909 rb->queue_post(disk_buf.q, STREAM_QUIT, 0); 909 rb->queue_post(disk_buf.q, STREAM_QUIT, 0);
910 rb->thread_wait(disk_buf.thread); 910 rb->thread_wait(disk_buf.thread);
911 disk_buf.thread = NULL; 911 disk_buf.thread = 0;
912 } 912 }
913} 913}
diff --git a/apps/plugins/mpegplayer/disk_buf.h b/apps/plugins/mpegplayer/disk_buf.h
index b6399c81d1..e16939a92e 100644
--- a/apps/plugins/mpegplayer/disk_buf.h
+++ b/apps/plugins/mpegplayer/disk_buf.h
@@ -62,7 +62,7 @@ struct dbuf_range
62 * playback events as well as buffering */ 62 * playback events as well as buffering */
63struct disk_buf 63struct disk_buf
64{ 64{
65 struct thread_entry *thread; 65 unsigned int thread;
66 struct event_queue *q; 66 struct event_queue *q;
67 uint8_t *start; /* Start pointer */ 67 uint8_t *start; /* Start pointer */
68 uint8_t *end; /* End of buffer pointer less MPEG_GUARDBUF_SIZE. The 68 uint8_t *end; /* End of buffer pointer less MPEG_GUARDBUF_SIZE. The
diff --git a/apps/plugins/mpegplayer/mpeg_parser.c b/apps/plugins/mpegplayer/mpeg_parser.c
index 54a6f23d92..42c388b375 100644
--- a/apps/plugins/mpegplayer/mpeg_parser.c
+++ b/apps/plugins/mpegplayer/mpeg_parser.c
@@ -1027,7 +1027,7 @@ intptr_t parser_send_video_msg(long id, intptr_t data)
1027{ 1027{
1028 intptr_t retval = 0; 1028 intptr_t retval = 0;
1029 1029
1030 if (video_str.thread != NULL && disk_buf.in_file >= 0) 1030 if (video_str.thread != 0 && disk_buf.in_file >= 0)
1031 { 1031 {
1032 /* Hook certain messages since they involve multiple operations 1032 /* Hook certain messages since they involve multiple operations
1033 * behind the scenes */ 1033 * behind the scenes */
diff --git a/apps/plugins/mpegplayer/stream_mgr.c b/apps/plugins/mpegplayer/stream_mgr.c
index 424d2fe503..222ffb7d6b 100644
--- a/apps/plugins/mpegplayer/stream_mgr.c
+++ b/apps/plugins/mpegplayer/stream_mgr.c
@@ -908,7 +908,7 @@ static void stream_mgr_thread(void)
908/* Opens a new file */ 908/* Opens a new file */
909int stream_open(const char *filename) 909int stream_open(const char *filename)
910{ 910{
911 if (stream_mgr.thread != NULL) 911 if (stream_mgr.thread != 0)
912 return stream_mgr_send_msg(STREAM_OPEN, (intptr_t)filename); 912 return stream_mgr_send_msg(STREAM_OPEN, (intptr_t)filename);
913 return STREAM_ERROR; 913 return STREAM_ERROR;
914} 914}
@@ -916,7 +916,7 @@ int stream_open(const char *filename)
916/* Plays the current file starting at time 'start' */ 916/* Plays the current file starting at time 'start' */
917int stream_play(void) 917int stream_play(void)
918{ 918{
919 if (stream_mgr.thread != NULL) 919 if (stream_mgr.thread != 0)
920 return stream_mgr_send_msg(STREAM_PLAY, 0); 920 return stream_mgr_send_msg(STREAM_PLAY, 0);
921 return STREAM_ERROR; 921 return STREAM_ERROR;
922} 922}
@@ -924,7 +924,7 @@ int stream_play(void)
924/* Pauses playback if playing */ 924/* Pauses playback if playing */
925int stream_pause(void) 925int stream_pause(void)
926{ 926{
927 if (stream_mgr.thread != NULL) 927 if (stream_mgr.thread != 0)
928 return stream_mgr_send_msg(STREAM_PAUSE, false); 928 return stream_mgr_send_msg(STREAM_PAUSE, false);
929 return STREAM_ERROR; 929 return STREAM_ERROR;
930} 930}
@@ -932,7 +932,7 @@ int stream_pause(void)
932/* Resumes playback if paused */ 932/* Resumes playback if paused */
933int stream_resume(void) 933int stream_resume(void)
934{ 934{
935 if (stream_mgr.thread != NULL) 935 if (stream_mgr.thread != 0)
936 return stream_mgr_send_msg(STREAM_PAUSE, true); 936 return stream_mgr_send_msg(STREAM_PAUSE, true);
937 return STREAM_ERROR; 937 return STREAM_ERROR;
938} 938}
@@ -940,7 +940,7 @@ int stream_resume(void)
940/* Stops playback if not stopped */ 940/* Stops playback if not stopped */
941int stream_stop(void) 941int stream_stop(void)
942{ 942{
943 if (stream_mgr.thread != NULL) 943 if (stream_mgr.thread != 0)
944 return stream_mgr_send_msg(STREAM_STOP, 0); 944 return stream_mgr_send_msg(STREAM_STOP, 0);
945 return STREAM_ERROR; 945 return STREAM_ERROR;
946} 946}
@@ -950,7 +950,7 @@ int stream_seek(uint32_t time, int whence)
950{ 950{
951 int ret; 951 int ret;
952 952
953 if (stream_mgr.thread == NULL) 953 if (stream_mgr.thread == 0)
954 return STREAM_ERROR; 954 return STREAM_ERROR;
955 955
956 stream_mgr_lock(); 956 stream_mgr_lock();
@@ -968,7 +968,7 @@ int stream_seek(uint32_t time, int whence)
968/* Closes the current file */ 968/* Closes the current file */
969int stream_close(void) 969int stream_close(void)
970{ 970{
971 if (stream_mgr.thread != NULL) 971 if (stream_mgr.thread != 0)
972 return stream_mgr_send_msg(STREAM_CLOSE, 0); 972 return stream_mgr_send_msg(STREAM_CLOSE, 0);
973 return STREAM_ERROR; 973 return STREAM_ERROR;
974} 974}
@@ -1018,7 +1018,7 @@ int stream_init(void)
1018 rb->queue_enable_queue_send(stream_mgr.q, &stream_mgr_queue_send, 1018 rb->queue_enable_queue_send(stream_mgr.q, &stream_mgr_queue_send,
1019 stream_mgr.thread); 1019 stream_mgr.thread);
1020 1020
1021 if (stream_mgr.thread == NULL) 1021 if (stream_mgr.thread == 0)
1022 { 1022 {
1023 rb->splash(HZ, "Could not create stream manager thread!"); 1023 rb->splash(HZ, "Could not create stream manager thread!");
1024 return STREAM_ERROR; 1024 return STREAM_ERROR;
@@ -1073,11 +1073,11 @@ void stream_exit(void)
1073 disk_buf_exit(); 1073 disk_buf_exit();
1074 pcm_output_exit(); 1074 pcm_output_exit();
1075 1075
1076 if (stream_mgr.thread != NULL) 1076 if (stream_mgr.thread != 0)
1077 { 1077 {
1078 stream_mgr_post_msg(STREAM_QUIT, 0); 1078 stream_mgr_post_msg(STREAM_QUIT, 0);
1079 rb->thread_wait(stream_mgr.thread); 1079 rb->thread_wait(stream_mgr.thread);
1080 stream_mgr.thread = NULL; 1080 stream_mgr.thread = 0;
1081 } 1081 }
1082 1082
1083#ifndef HAVE_LCD_COLOR 1083#ifndef HAVE_LCD_COLOR
diff --git a/apps/plugins/mpegplayer/stream_mgr.h b/apps/plugins/mpegplayer/stream_mgr.h
index e3ea9207e6..a00b39f189 100644
--- a/apps/plugins/mpegplayer/stream_mgr.h
+++ b/apps/plugins/mpegplayer/stream_mgr.h
@@ -27,7 +27,7 @@
27 * coordination with assistance from the parser */ 27 * coordination with assistance from the parser */
28struct stream_mgr 28struct stream_mgr
29{ 29{
30 struct thread_entry *thread; /* Playback control thread */ 30 unsigned int thread; /* Playback control thread */
31 struct event_queue *q; /* event queue for control thread */ 31 struct event_queue *q; /* event queue for control thread */
32 const char *filename; /* Current filename */ 32 const char *filename; /* Current filename */
33 uint32_t resume_time; /* The stream tick where playback was 33 uint32_t resume_time; /* The stream tick where playback was
diff --git a/apps/plugins/mpegplayer/stream_thread.h b/apps/plugins/mpegplayer/stream_thread.h
index d6e42d274f..30bf46e6ff 100644
--- a/apps/plugins/mpegplayer/stream_thread.h
+++ b/apps/plugins/mpegplayer/stream_thread.h
@@ -45,7 +45,7 @@ struct stream_hdr
45struct stream 45struct stream
46{ 46{
47 struct stream_hdr hdr; /* Base stream data */ 47 struct stream_hdr hdr; /* Base stream data */
48 struct thread_entry *thread; /* Stream's thread */ 48 unsigned int thread; /* Stream's thread */
49 uint8_t* curr_packet; /* Current stream packet beginning */ 49 uint8_t* curr_packet; /* Current stream packet beginning */
50 uint8_t* curr_packet_end; /* Current stream packet end */ 50 uint8_t* curr_packet_end; /* Current stream packet end */
51 struct list_item l; /* List of streams - either reserve pool 51 struct list_item l; /* List of streams - either reserve pool
diff --git a/apps/plugins/mpegplayer/video_thread.c b/apps/plugins/mpegplayer/video_thread.c
index 100904b01b..8b84686a3b 100644
--- a/apps/plugins/mpegplayer/video_thread.c
+++ b/apps/plugins/mpegplayer/video_thread.c
@@ -1009,7 +1009,7 @@ bool video_thread_init(void)
1009 rb->queue_enable_queue_send(video_str.hdr.q, &video_str_queue_send, 1009 rb->queue_enable_queue_send(video_str.hdr.q, &video_str_queue_send,
1010 video_str.thread); 1010 video_str.thread);
1011 1011
1012 if (video_str.thread == NULL) 1012 if (video_str.thread == 0)
1013 return false; 1013 return false;
1014 1014
1015 /* Wait for thread to initialize */ 1015 /* Wait for thread to initialize */
@@ -1022,11 +1022,11 @@ bool video_thread_init(void)
1022/* Terminates the video thread */ 1022/* Terminates the video thread */
1023void video_thread_exit(void) 1023void video_thread_exit(void)
1024{ 1024{
1025 if (video_str.thread != NULL) 1025 if (video_str.thread != 0)
1026 { 1026 {
1027 str_post_msg(&video_str, STREAM_QUIT, 0); 1027 str_post_msg(&video_str, STREAM_QUIT, 0);
1028 rb->thread_wait(video_str.thread); 1028 rb->thread_wait(video_str.thread);
1029 IF_COP(invalidate_icache()); 1029 IF_COP(invalidate_icache());
1030 video_str.thread = NULL; 1030 video_str.thread = 0;
1031 } 1031 }
1032} 1032}
diff --git a/apps/plugins/pictureflow.c b/apps/plugins/pictureflow.c
index 29e8a749d5..232c3f6bc4 100644
--- a/apps/plugins/pictureflow.c
+++ b/apps/plugins/pictureflow.c
@@ -218,7 +218,7 @@ struct mutex slide_cache_stack_lock;
218 218
219static int empty_slide_hid; 219static int empty_slide_hid;
220 220
221struct thread_entry *thread_id; 221unsigned int thread_id;
222struct event_queue thread_q; 222struct event_queue thread_q;
223 223
224static char tmp_path_name[MAX_PATH]; 224static char tmp_path_name[MAX_PATH];
@@ -831,7 +831,7 @@ bool create_pf_thread(void)
831 IF_PRIO(, PRIORITY_BACKGROUND) 831 IF_PRIO(, PRIORITY_BACKGROUND)
832 IF_COP(, CPU) 832 IF_COP(, CPU)
833 ) 833 )
834 ) == NULL) { 834 ) == 0) {
835 return false; 835 return false;
836 } 836 }
837 thread_is_running = true; 837 thread_is_running = true;
diff --git a/apps/plugins/test_codec.c b/apps/plugins/test_codec.c
index b1f5aff385..17effd8dfd 100644
--- a/apps/plugins/test_codec.c
+++ b/apps/plugins/test_codec.c
@@ -525,7 +525,7 @@ static enum plugin_status test_track(const char* filename)
525 long ticks; 525 long ticks;
526 unsigned long speed; 526 unsigned long speed;
527 unsigned long duration; 527 unsigned long duration;
528 struct thread_entry* codecthread_id; 528 unsigned int codecthread_id;
529 const char* ch; 529 const char* ch;
530 530
531 /* Display filename (excluding any path)*/ 531 /* Display filename (excluding any path)*/
@@ -590,7 +590,7 @@ static enum plugin_status test_track(const char* filename)
590 590
591 if ((codecthread_id = rb->create_thread(codec_thread, 591 if ((codecthread_id = rb->create_thread(codec_thread,
592 codec_stack, codec_stack_size, 0, "testcodec" 592 codec_stack, codec_stack_size, 0, "testcodec"
593 IF_PRIO(,PRIORITY_PLAYBACK) IF_COP(, CPU))) == NULL) 593 IF_PRIO(,PRIORITY_PLAYBACK) IF_COP(, CPU))) == 0)
594 { 594 {
595 log_text("Cannot create codec thread!",true); 595 log_text("Cannot create codec thread!",true);
596 goto exit; 596 goto exit;
diff --git a/apps/plugins/test_sampr.c b/apps/plugins/test_sampr.c
index 77f9b8a779..1131a7a989 100644
--- a/apps/plugins/test_sampr.c
+++ b/apps/plugins/test_sampr.c
@@ -39,7 +39,7 @@ static unsigned long hw_sampr IDATA_ATTR = HW_SAMPR_DEFAULT;
39 39
40static int gen_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)] IBSS_ATTR; 40static int gen_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)] IBSS_ATTR;
41static bool gen_quit IBSS_ATTR; 41static bool gen_quit IBSS_ATTR;
42static struct thread_entry *gen_thread_p; 42static unsigned int gen_thread_id;
43 43
44#define OUTPUT_CHUNK_COUNT (1 << 1) 44#define OUTPUT_CHUNK_COUNT (1 << 1)
45#define OUTPUT_CHUNK_MASK (OUTPUT_CHUNK_COUNT-1) 45#define OUTPUT_CHUNK_MASK (OUTPUT_CHUNK_COUNT-1)
@@ -233,11 +233,11 @@ static void play_tone(bool volume_set)
233 output_clear(); 233 output_clear();
234 update_gen_step(); 234 update_gen_step();
235 235
236 gen_thread_p = rb->create_thread(gen_thread_func, gen_thread_stack, 236 gen_thread_id = rb->create_thread(gen_thread_func, gen_thread_stack,
237 sizeof(gen_thread_stack), 0, 237 sizeof(gen_thread_stack), 0,
238 "test_sampr generator" 238 "test_sampr generator"
239 IF_PRIO(, PRIORITY_PLAYBACK) 239 IF_PRIO(, PRIORITY_PLAYBACK)
240 IF_COP(, CPU)); 240 IF_COP(, CPU));
241 241
242 rb->pcm_play_data(get_more, NULL, 0); 242 rb->pcm_play_data(get_more, NULL, 0);
243 243
@@ -260,7 +260,7 @@ static void play_tone(bool volume_set)
260 260
261 gen_quit = true; 261 gen_quit = true;
262 262
263 rb->thread_wait(gen_thread_p); 263 rb->thread_wait(gen_thread_id);
264 264
265 rb->pcm_play_stop(); 265 rb->pcm_play_stop();
266 266
diff --git a/apps/recorder/pcm_record.c b/apps/recorder/pcm_record.c
index dbbc6901ec..9ceb68c796 100644
--- a/apps/recorder/pcm_record.c
+++ b/apps/recorder/pcm_record.c
@@ -37,7 +37,7 @@
37 37
38/***************************************************************************/ 38/***************************************************************************/
39 39
40extern struct thread_entry *codec_thread_p; 40extern uintptr_t codec_thread_id;
41 41
42/** General recording state **/ 42/** General recording state **/
43static bool is_recording; /* We are recording */ 43static bool is_recording; /* We are recording */
@@ -220,7 +220,7 @@ static struct event_queue pcmrec_queue SHAREDBSS_ATTR;
220static struct queue_sender_list pcmrec_queue_send SHAREDBSS_ATTR; 220static struct queue_sender_list pcmrec_queue_send SHAREDBSS_ATTR;
221static long pcmrec_stack[3*DEFAULT_STACK_SIZE/sizeof(long)]; 221static long pcmrec_stack[3*DEFAULT_STACK_SIZE/sizeof(long)];
222static const char pcmrec_thread_name[] = "pcmrec"; 222static const char pcmrec_thread_name[] = "pcmrec";
223static struct thread_entry *pcmrec_thread_p; 223static unsigned int pcmrec_thread_id = 0;
224 224
225static void pcmrec_thread(void); 225static void pcmrec_thread(void);
226 226
@@ -365,12 +365,12 @@ unsigned long pcm_rec_sample_rate(void)
365void pcm_rec_init(void) 365void pcm_rec_init(void)
366{ 366{
367 queue_init(&pcmrec_queue, true); 367 queue_init(&pcmrec_queue, true);
368 pcmrec_thread_p = 368 pcmrec_thread_id =
369 create_thread(pcmrec_thread, pcmrec_stack, sizeof(pcmrec_stack), 369 create_thread(pcmrec_thread, pcmrec_stack, sizeof(pcmrec_stack),
370 0, pcmrec_thread_name IF_PRIO(, PRIORITY_RECORDING) 370 0, pcmrec_thread_name IF_PRIO(, PRIORITY_RECORDING)
371 IF_COP(, CPU)); 371 IF_COP(, CPU));
372 queue_enable_queue_send(&pcmrec_queue, &pcmrec_queue_send, 372 queue_enable_queue_send(&pcmrec_queue, &pcmrec_queue_send,
373 pcmrec_thread_p); 373 pcmrec_thread_id);
374} /* pcm_rec_init */ 374} /* pcm_rec_init */
375 375
376/** audio_* group **/ 376/** audio_* group **/
@@ -878,10 +878,10 @@ static void pcmrec_flush(unsigned flush_num)
878 priority until finished */ 878 priority until finished */
879 logf("pcmrec: boost (%s)", 879 logf("pcmrec: boost (%s)",
880 num >= flood_watermark ? "num" : "time"); 880 num >= flood_watermark ? "num" : "time");
881 prio_pcmrec = thread_set_priority(NULL, 881 prio_pcmrec = thread_set_priority(THREAD_ID_CURRENT,
882 thread_get_priority(NULL) - 4); 882 thread_get_priority(THREAD_ID_CURRENT) - 4);
883 prio_codec = thread_set_priority(codec_thread_p, 883 prio_codec = thread_set_priority(codec_thread_id,
884 thread_get_priority(codec_thread_p) - 4); 884 thread_get_priority(codec_thread_id) - 4);
885 } 885 }
886#endif 886#endif
887 887
@@ -931,8 +931,8 @@ static void pcmrec_flush(unsigned flush_num)
931 { 931 {
932 /* return to original priorities */ 932 /* return to original priorities */
933 logf("pcmrec: unboost priority"); 933 logf("pcmrec: unboost priority");
934 thread_set_priority(NULL, prio_pcmrec); 934 thread_set_priority(THREAD_ID_CURRENT, prio_pcmrec);
935 thread_set_priority(codec_thread_p, prio_codec); 935 thread_set_priority(codec_thread_id, prio_codec);
936 } 936 }
937 937
938 last_flush_tick = current_tick; /* save tick when we left */ 938 last_flush_tick = current_tick; /* save tick when we left */
diff --git a/apps/voice_thread.c b/apps/voice_thread.c
index 084c3872c6..86e80cece3 100644
--- a/apps/voice_thread.c
+++ b/apps/voice_thread.c
@@ -54,7 +54,7 @@
54#define VOICE_SAMPLE_DEPTH 16 /* Sample depth in bits */ 54#define VOICE_SAMPLE_DEPTH 16 /* Sample depth in bits */
55 55
56/* Voice thread variables */ 56/* Voice thread variables */
57static struct thread_entry *voice_thread_p = NULL; 57static unsigned int voice_thread_id = 0;
58static long voice_stack[0x7c0/sizeof(long)] IBSS_ATTR_VOICE_STACK; 58static long voice_stack[0x7c0/sizeof(long)] IBSS_ATTR_VOICE_STACK;
59static const char voice_thread_name[] = "voice"; 59static const char voice_thread_name[] = "voice";
60 60
@@ -434,25 +434,25 @@ void voice_thread_init(void)
434 queue_init(&voice_queue, false); 434 queue_init(&voice_queue, false);
435 mutex_init(&voice_mutex); 435 mutex_init(&voice_mutex);
436 436
437 voice_thread_p = create_thread(voice_thread, voice_stack, 437 voice_thread_id = create_thread(voice_thread, voice_stack,
438 sizeof(voice_stack), CREATE_THREAD_FROZEN, 438 sizeof(voice_stack), CREATE_THREAD_FROZEN,
439 voice_thread_name IF_PRIO(, PRIORITY_PLAYBACK) IF_COP(, CPU)); 439 voice_thread_name IF_PRIO(, PRIORITY_PLAYBACK) IF_COP(, CPU));
440 440
441 queue_enable_queue_send(&voice_queue, &voice_queue_sender_list, 441 queue_enable_queue_send(&voice_queue, &voice_queue_sender_list,
442 voice_thread_p); 442 voice_thread_id);
443} /* voice_thread_init */ 443} /* voice_thread_init */
444 444
445/* Unfreeze the voice thread */ 445/* Unfreeze the voice thread */
446void voice_thread_resume(void) 446void voice_thread_resume(void)
447{ 447{
448 logf("Thawing voice thread"); 448 logf("Thawing voice thread");
449 thread_thaw(voice_thread_p); 449 thread_thaw(voice_thread_id);
450} 450}
451 451
452#ifdef HAVE_PRIORITY_SCHEDULING 452#ifdef HAVE_PRIORITY_SCHEDULING
453/* Set the voice thread priority */ 453/* Set the voice thread priority */
454void voice_thread_set_priority(int priority) 454void voice_thread_set_priority(int priority)
455{ 455{
456 thread_set_priority(voice_thread_p, priority); 456 thread_set_priority(voice_thread_id, priority);
457} 457}
458#endif 458#endif
diff --git a/firmware/backlight.c b/firmware/backlight.c
index 07cc9532be..66cc6df569 100644
--- a/firmware/backlight.c
+++ b/firmware/backlight.c
@@ -130,7 +130,7 @@ static long backlight_stack[DEFAULT_STACK_SIZE/sizeof(long)];
130static const char backlight_thread_name[] = "backlight"; 130static const char backlight_thread_name[] = "backlight";
131static struct event_queue backlight_queue; 131static struct event_queue backlight_queue;
132#ifdef BACKLIGHT_DRIVER_CLOSE 132#ifdef BACKLIGHT_DRIVER_CLOSE
133static struct thread_entry *backlight_thread_p = NULL; 133static unsigned int backlight_thread_id = 0;
134#endif 134#endif
135 135
136static int backlight_timer SHAREDBSS_ATTR; 136static int backlight_timer SHAREDBSS_ATTR;
@@ -744,7 +744,7 @@ void backlight_init(void)
744 * call the appropriate backlight_set_*() functions, only changing light 744 * call the appropriate backlight_set_*() functions, only changing light
745 * status if necessary. */ 745 * status if necessary. */
746#ifdef BACKLIGHT_DRIVER_CLOSE 746#ifdef BACKLIGHT_DRIVER_CLOSE
747 backlight_thread_p = 747 backlight_thread_id =
748#endif 748#endif
749 create_thread(backlight_thread, backlight_stack, 749 create_thread(backlight_thread, backlight_stack,
750 sizeof(backlight_stack), 0, backlight_thread_name 750 sizeof(backlight_stack), 0, backlight_thread_name
@@ -756,13 +756,13 @@ void backlight_init(void)
756#ifdef BACKLIGHT_DRIVER_CLOSE 756#ifdef BACKLIGHT_DRIVER_CLOSE
757void backlight_close(void) 757void backlight_close(void)
758{ 758{
759 struct thread_entry *thread = backlight_thread_p; 759 unsigned int thread = backlight_thread_id;
760 760
761 /* Wait for thread to exit */ 761 /* Wait for thread to exit */
762 if (thread == NULL) 762 if (thread == 0)
763 return; 763 return;
764 764
765 backlight_thread_p = NULL; 765 backlight_thread_id = 0;
766 766
767 queue_post(&backlight_queue, BACKLIGHT_QUIT, 0); 767 queue_post(&backlight_queue, BACKLIGHT_QUIT, 0);
768 thread_wait(thread); 768 thread_wait(thread);
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 00a7c3e19a..e3fa3e8958 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -71,7 +71,7 @@
71#endif 71#endif
72 72
73#ifdef ATA_DRIVER_CLOSE 73#ifdef ATA_DRIVER_CLOSE
74static struct thread_entry *ata_thread_p = NULL; 74static unsigned int ata_thread_id = 0;
75#endif 75#endif
76 76
77#if defined(MAX_PHYS_SECTOR_SIZE) && MEM == 64 77#if defined(MAX_PHYS_SECTOR_SIZE) && MEM == 64
@@ -94,7 +94,8 @@ static void ata_lock_init(struct ata_lock *l)
94 94
95static void ata_lock_lock(struct ata_lock *l) 95static void ata_lock_lock(struct ata_lock *l)
96{ 96{
97 struct thread_entry * const current = thread_get_current(); 97 struct thread_entry * const current =
98 thread_id_entry(THREAD_ID_CURRENT);
98 99
99 if (current == l->thread) 100 if (current == l->thread)
100 { 101 {
@@ -1350,7 +1351,7 @@ int ata_init(void)
1350 1351
1351 last_disk_activity = current_tick; 1352 last_disk_activity = current_tick;
1352#ifdef ATA_DRIVER_CLOSE 1353#ifdef ATA_DRIVER_CLOSE
1353 ata_thread_p = 1354 ata_thread_id =
1354#endif 1355#endif
1355 create_thread(ata_thread, ata_stack, 1356 create_thread(ata_thread, ata_stack,
1356 sizeof(ata_stack), 0, ata_thread_name 1357 sizeof(ata_stack), 0, ata_thread_name
@@ -1370,15 +1371,15 @@ int ata_init(void)
1370#ifdef ATA_DRIVER_CLOSE 1371#ifdef ATA_DRIVER_CLOSE
1371void ata_close(void) 1372void ata_close(void)
1372{ 1373{
1373 struct thread_entry *thread = ata_thread_p; 1374 unsigned int thread_id = ata_thread_id;
1374 1375
1375 if (thread == NULL) 1376 if (thread_id == 0)
1376 return; 1377 return;
1377 1378
1378 ata_thread_p = NULL; 1379 ata_thread_id = 0;
1379 1380
1380 queue_post(&ata_queue, Q_CLOSE, 0); 1381 queue_post(&ata_queue, Q_CLOSE, 0);
1381 thread_wait(thread); 1382 thread_wait(thread_id);
1382} 1383}
1383#endif /* ATA_DRIVER_CLOSE */ 1384#endif /* ATA_DRIVER_CLOSE */
1384 1385
diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h
index beba58eb21..ef65463e5d 100644
--- a/firmware/export/kernel.h
+++ b/firmware/export/kernel.h
@@ -261,7 +261,7 @@ extern void queue_post(struct event_queue *q, long id, intptr_t data);
261#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME 261#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
262extern void queue_enable_queue_send(struct event_queue *q, 262extern void queue_enable_queue_send(struct event_queue *q,
263 struct queue_sender_list *send, 263 struct queue_sender_list *send,
264 struct thread_entry *owner); 264 unsigned int owner_id);
265extern intptr_t queue_send(struct event_queue *q, long id, intptr_t data); 265extern intptr_t queue_send(struct event_queue *q, long id, intptr_t data);
266extern void queue_reply(struct event_queue *q, intptr_t retval); 266extern void queue_reply(struct event_queue *q, intptr_t retval);
267extern bool queue_in_queue_send(struct event_queue *q); 267extern bool queue_in_queue_send(struct event_queue *q);
diff --git a/firmware/export/thread.h b/firmware/export/thread.h
index c4dfbf4ed3..4c1e952347 100644
--- a/firmware/export/thread.h
+++ b/firmware/export/thread.h
@@ -58,9 +58,6 @@
58#define NUM_PRIORITIES 32 58#define NUM_PRIORITIES 32
59#define PRIORITY_IDLE 32 /* Priority representative of no tasks */ 59#define PRIORITY_IDLE 32 /* Priority representative of no tasks */
60 60
61/* TODO: Only a minor tweak to create_thread would be needed to let
62 * thread slots be caller allocated - no essential threading functionality
63 * depends upon an array */
64#if CONFIG_CODEC == SWCODEC 61#if CONFIG_CODEC == SWCODEC
65 62
66#ifdef HAVE_RECORDING 63#ifdef HAVE_RECORDING
@@ -280,6 +277,7 @@ struct thread_entry
280 int skip_count; /* Number of times skipped if higher priority 277 int skip_count; /* Number of times skipped if higher priority
281 thread was running */ 278 thread was running */
282#endif 279#endif
280 uint16_t id; /* Current slot id */
283 unsigned short stack_size; /* Size of stack in bytes */ 281 unsigned short stack_size; /* Size of stack in bytes */
284#ifdef HAVE_PRIORITY_SCHEDULING 282#ifdef HAVE_PRIORITY_SCHEDULING
285 unsigned char base_priority; /* Base priority (set explicitly during 283 unsigned char base_priority; /* Base priority (set explicitly during
@@ -298,6 +296,16 @@ struct thread_entry
298#endif 296#endif
299}; 297};
300 298
299/*** Macros for internal use ***/
300/* Thread ID, 16 bits = |VVVVVVVV|SSSSSSSS| */
301#define THREAD_ID_VERSION_SHIFT 8
302#define THREAD_ID_VERSION_MASK 0xff00
303#define THREAD_ID_SLOT_MASK 0x00ff
304#define THREAD_ID_INIT(n) ((1u << THREAD_ID_VERSION_SHIFT) | (n))
305
306/* Specify current thread in a function taking an ID. */
307#define THREAD_ID_CURRENT ((unsigned int)-1)
308
301#if NUM_CORES > 1 309#if NUM_CORES > 1
302/* Operations to be performed just before stopping a thread and starting 310/* Operations to be performed just before stopping a thread and starting
303 a new one if specified before calling switch_thread */ 311 a new one if specified before calling switch_thread */
@@ -475,11 +483,11 @@ void init_threads(void);
475 483
476/* Allocate a thread in the scheduler */ 484/* Allocate a thread in the scheduler */
477#define CREATE_THREAD_FROZEN 0x00000001 /* Thread is frozen at create time */ 485#define CREATE_THREAD_FROZEN 0x00000001 /* Thread is frozen at create time */
478struct thread_entry* 486unsigned int create_thread(void (*function)(void),
479 create_thread(void (*function)(void), void* stack, size_t stack_size, 487 void* stack, size_t stack_size,
480 unsigned flags, const char *name 488 unsigned flags, const char *name
481 IF_PRIO(, int priority) 489 IF_PRIO(, int priority)
482 IF_COP(, unsigned int core)); 490 IF_COP(, unsigned int core));
483 491
484/* Set and clear the CPU frequency boost flag for the calling thread */ 492/* Set and clear the CPU frequency boost flag for the calling thread */
485#ifdef HAVE_SCHEDULER_BOOSTCTRL 493#ifdef HAVE_SCHEDULER_BOOSTCTRL
@@ -489,17 +497,19 @@ void cancel_cpu_boost(void);
489#define trigger_cpu_boost() 497#define trigger_cpu_boost()
490#define cancel_cpu_boost() 498#define cancel_cpu_boost()
491#endif 499#endif
500/* Return thread entry from id */
501struct thread_entry *thread_id_entry(unsigned int thread_id);
492/* Make a frozed thread runnable (when started with CREATE_THREAD_FROZEN). 502/* Make a frozed thread runnable (when started with CREATE_THREAD_FROZEN).
493 * Has no effect on a thread not frozen. */ 503 * Has no effect on a thread not frozen. */
494void thread_thaw(struct thread_entry *thread); 504void thread_thaw(unsigned int thread_id);
495/* Wait for a thread to exit */ 505/* Wait for a thread to exit */
496void thread_wait(struct thread_entry *thread); 506void thread_wait(unsigned int thread_id);
497/* Exit the current thread */ 507/* Exit the current thread */
498void thread_exit(void); 508void thread_exit(void);
499#if defined(DEBUG) || defined(ROCKBOX_HAS_LOGF) 509#if defined(DEBUG) || defined(ROCKBOX_HAS_LOGF)
500#define ALLOW_REMOVE_THREAD 510#define ALLOW_REMOVE_THREAD
501/* Remove a thread from the scheduler */ 511/* Remove a thread from the scheduler */
502void remove_thread(struct thread_entry *thread); 512void remove_thread(unsigned int thread_id);
503#endif 513#endif
504 514
505/* Switch to next runnable thread */ 515/* Switch to next runnable thread */
@@ -526,13 +536,13 @@ unsigned int thread_queue_wake(struct thread_entry **list);
526unsigned int wakeup_thread(struct thread_entry **list); 536unsigned int wakeup_thread(struct thread_entry **list);
527 537
528#ifdef HAVE_PRIORITY_SCHEDULING 538#ifdef HAVE_PRIORITY_SCHEDULING
529int thread_set_priority(struct thread_entry *thread, int priority); 539int thread_set_priority(unsigned int thread_id, int priority);
530int thread_get_priority(struct thread_entry *thread); 540int thread_get_priority(unsigned int thread_id);
531#endif /* HAVE_PRIORITY_SCHEDULING */ 541#endif /* HAVE_PRIORITY_SCHEDULING */
532#if NUM_CORES > 1 542#if NUM_CORES > 1
533unsigned int switch_core(unsigned int new_core); 543unsigned int switch_core(unsigned int new_core);
534#endif 544#endif
535struct thread_entry * thread_get_current(void); 545unsigned int thread_get_current(void);
536 546
537/* Debugging info - only! */ 547/* Debugging info - only! */
538int thread_stack_usage(const struct thread_entry *thread); 548int thread_stack_usage(const struct thread_entry *thread);
diff --git a/firmware/kernel.c b/firmware/kernel.c
index 920893818a..553f6721a1 100644
--- a/firmware/kernel.c
+++ b/firmware/kernel.c
@@ -352,11 +352,12 @@ static void queue_remove_sender_thread_cb(struct thread_entry *thread)
352 * specified for priority inheritance to operate. 352 * specified for priority inheritance to operate.
353 * 353 *
354 * Use of queue_wait(_w_tmo) by multiple threads on a queue using synchronous 354 * Use of queue_wait(_w_tmo) by multiple threads on a queue using synchronous
355 * messages results in an undefined order of message replies. 355 * messages results in an undefined order of message replies or possible default
356 * replies if two or more waits happen before a reply is done.
356 */ 357 */
357void queue_enable_queue_send(struct event_queue *q, 358void queue_enable_queue_send(struct event_queue *q,
358 struct queue_sender_list *send, 359 struct queue_sender_list *send,
359 struct thread_entry *owner) 360 unsigned int owner_id)
360{ 361{
361 int oldlevel = disable_irq_save(); 362 int oldlevel = disable_irq_save();
362 corelock_lock(&q->cl); 363 corelock_lock(&q->cl);
@@ -367,9 +368,11 @@ void queue_enable_queue_send(struct event_queue *q,
367#ifdef HAVE_PRIORITY_SCHEDULING 368#ifdef HAVE_PRIORITY_SCHEDULING
368 send->blocker.wakeup_protocol = wakeup_priority_protocol_release; 369 send->blocker.wakeup_protocol = wakeup_priority_protocol_release;
369 send->blocker.priority = PRIORITY_IDLE; 370 send->blocker.priority = PRIORITY_IDLE;
370 send->blocker.thread = owner; 371 if(owner_id != 0)
371 if(owner != NULL) 372 {
373 send->blocker.thread = thread_id_entry(owner_id);
372 q->blocker_p = &send->blocker; 374 q->blocker_p = &send->blocker;
375 }
373#endif 376#endif
374 q->send = send; 377 q->send = send;
375 } 378 }
@@ -377,7 +380,7 @@ void queue_enable_queue_send(struct event_queue *q,
377 corelock_unlock(&q->cl); 380 corelock_unlock(&q->cl);
378 restore_irq(oldlevel); 381 restore_irq(oldlevel);
379 382
380 (void)owner; 383 (void)owner_id;
381} 384}
382 385
383/* Unblock a blocked thread at a given event index */ 386/* Unblock a blocked thread at a given event index */
@@ -532,7 +535,7 @@ void queue_wait(struct event_queue *q, struct queue_event *ev)
532 535
533#ifdef HAVE_PRIORITY_SCHEDULING 536#ifdef HAVE_PRIORITY_SCHEDULING
534 KERNEL_ASSERT(QUEUE_GET_THREAD(q) == NULL || 537 KERNEL_ASSERT(QUEUE_GET_THREAD(q) == NULL ||
535 QUEUE_GET_THREAD(q) == thread_get_current(), 538 QUEUE_GET_THREAD(q) == cores[CURRENT_CORE].running,
536 "queue_wait->wrong thread\n"); 539 "queue_wait->wrong thread\n");
537#endif 540#endif
538 541
@@ -579,7 +582,7 @@ void queue_wait_w_tmo(struct event_queue *q, struct queue_event *ev, int ticks)
579 582
580#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME 583#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
581 KERNEL_ASSERT(QUEUE_GET_THREAD(q) == NULL || 584 KERNEL_ASSERT(QUEUE_GET_THREAD(q) == NULL ||
582 QUEUE_GET_THREAD(q) == thread_get_current(), 585 QUEUE_GET_THREAD(q) == cores[CURRENT_CORE].running,
583 "queue_wait_w_tmo->wrong thread\n"); 586 "queue_wait_w_tmo->wrong thread\n");
584#endif 587#endif
585 588
@@ -914,10 +917,10 @@ void mutex_lock(struct mutex *m)
914void mutex_unlock(struct mutex *m) 917void mutex_unlock(struct mutex *m)
915{ 918{
916 /* unlocker not being the owner is an unlocking violation */ 919 /* unlocker not being the owner is an unlocking violation */
917 KERNEL_ASSERT(MUTEX_GET_THREAD(m) == thread_get_current(), 920 KERNEL_ASSERT(MUTEX_GET_THREAD(m) == cores[CURRENT_CORE].running,
918 "mutex_unlock->wrong thread (%s != %s)\n", 921 "mutex_unlock->wrong thread (%s != %s)\n",
919 MUTEX_GET_THREAD(m)->name, 922 MUTEX_GET_THREAD(m)->name,
920 thread_get_current()->name); 923 cores[CURRENT_CORE].running->name);
921 924
922 if(m->count > 0) 925 if(m->count > 0)
923 { 926 {
@@ -990,7 +993,7 @@ void spinlock_lock(struct spinlock *l)
990void spinlock_unlock(struct spinlock *l) 993void spinlock_unlock(struct spinlock *l)
991{ 994{
992 /* unlocker not being the owner is an unlocking violation */ 995 /* unlocker not being the owner is an unlocking violation */
993 KERNEL_ASSERT(l->thread == thread_get_current(), 996 KERNEL_ASSERT(l->thread == cores[CURRENT_CORE].running,
994 "spinlock_unlock->wrong thread\n"); 997 "spinlock_unlock->wrong thread\n");
995 998
996 if(l->count > 0) 999 if(l->count > 0)
diff --git a/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c b/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c
index c185994bfc..81849d0852 100644
--- a/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c
@@ -69,7 +69,7 @@ static const unsigned char pmic_ints_regs[2] =
69 69
70#ifdef PMIC_DRIVER_CLOSE 70#ifdef PMIC_DRIVER_CLOSE
71static bool pmic_close = false; 71static bool pmic_close = false;
72static struct thread_entry *mc13783_thread_p = NULL; 72static unsigned int mc13783_thread_id = 0;
73#endif 73#endif
74 74
75static void mc13783_interrupt_thread(void) 75static void mc13783_interrupt_thread(void)
@@ -149,7 +149,7 @@ void mc13783_init(void)
149 MC13783_GPIO_ISR = (1ul << MC13783_GPIO_LINE); 149 MC13783_GPIO_ISR = (1ul << MC13783_GPIO_LINE);
150 150
151#ifdef PMIC_DRIVER_CLOSE 151#ifdef PMIC_DRIVER_CLOSE
152 mc13783_thread_p = 152 mc13783_thread_id =
153#endif 153#endif
154 create_thread(mc13783_interrupt_thread, 154 create_thread(mc13783_interrupt_thread,
155 mc13783_thread_stack, sizeof(mc13783_thread_stack), 0, 155 mc13783_thread_stack, sizeof(mc13783_thread_stack), 0,
@@ -159,16 +159,16 @@ void mc13783_init(void)
159#ifdef PMIC_DRIVER_CLOSE 159#ifdef PMIC_DRIVER_CLOSE
160void mc13783_close(void) 160void mc13783_close(void)
161{ 161{
162 struct thread_entry *thread = mc13783_thread_p; 162 unsigned int thread_id = mc13783_thread_p;
163 163
164 if (thread == NULL) 164 if (thread_id == 0)
165 return; 165 return;
166 166
167 mc13783_thread_p = NULL; 167 mc13783_thread_id = 0;
168 168
169 pmic_close = true; 169 pmic_close = true;
170 wakeup_signal(&mc13783_wake); 170 wakeup_signal(&mc13783_wake);
171 thread_wait(thread); 171 thread_wait(thread_id);
172} 172}
173#endif /* PMIC_DRIVER_CLOSE */ 173#endif /* PMIC_DRIVER_CLOSE */
174 174
diff --git a/firmware/thread.c b/firmware/thread.c
index c500fc4818..377c3355b4 100644
--- a/firmware/thread.c
+++ b/firmware/thread.c
@@ -1691,8 +1691,8 @@ struct thread_entry *
1691 struct thread_entry *next; 1691 struct thread_entry *next;
1692 int bl_pr; 1692 int bl_pr;
1693 1693
1694 THREAD_ASSERT(thread_get_current() == bl_t, 1694 THREAD_ASSERT(cores[CURRENT_CORE].running == bl_t,
1695 "UPPT->wrong thread", thread_get_current()); 1695 "UPPT->wrong thread", cores[CURRENT_CORE].running);
1696 1696
1697 LOCK_THREAD(bl_t); 1697 LOCK_THREAD(bl_t);
1698 1698
@@ -2031,7 +2031,7 @@ void switch_thread(void)
2031 } 2031 }
2032 2032
2033#ifdef RB_PROFILE 2033#ifdef RB_PROFILE
2034 profile_thread_stopped(thread - threads); 2034 profile_thread_stopped(thread->id & THREAD_ID_SLOT_MASK);
2035#endif 2035#endif
2036 2036
2037 /* Begin task switching by saving our current context so that we can 2037 /* Begin task switching by saving our current context so that we can
@@ -2136,7 +2136,7 @@ void switch_thread(void)
2136 load_context(&thread->context); 2136 load_context(&thread->context);
2137 2137
2138#ifdef RB_PROFILE 2138#ifdef RB_PROFILE
2139 profile_thread_started(thread - threads); 2139 profile_thread_started(thread->id & THREAD_ID_SLOT_MASK);
2140#endif 2140#endif
2141 2141
2142} 2142}
@@ -2316,6 +2316,24 @@ unsigned int thread_queue_wake(struct thread_entry **list)
2316} 2316}
2317 2317
2318/*--------------------------------------------------------------------------- 2318/*---------------------------------------------------------------------------
2319 * Assign the thread slot a new ID. Version is 1-255.
2320 *---------------------------------------------------------------------------
2321 */
2322static void new_thread_id(unsigned int slot_num,
2323 struct thread_entry *thread)
2324{
2325 unsigned int version =
2326 (thread->id + (1u << THREAD_ID_VERSION_SHIFT))
2327 & THREAD_ID_VERSION_MASK;
2328
2329 /* If wrapped to 0, make it 1 */
2330 if (version == 0)
2331 version = 1u << THREAD_ID_VERSION_SHIFT;
2332
2333 thread->id = version | (slot_num & THREAD_ID_SLOT_MASK);
2334}
2335
2336/*---------------------------------------------------------------------------
2319 * Find an empty thread slot or MAXTHREADS if none found. The slot returned 2337 * Find an empty thread slot or MAXTHREADS if none found. The slot returned
2320 * will be locked on multicore. 2338 * will be locked on multicore.
2321 *--------------------------------------------------------------------------- 2339 *---------------------------------------------------------------------------
@@ -2349,6 +2367,17 @@ static struct thread_entry * find_empty_thread_slot(void)
2349 return thread; 2367 return thread;
2350} 2368}
2351 2369
2370/*---------------------------------------------------------------------------
2371 * Return the thread_entry pointer for a thread_id. Return the current
2372 * thread if the ID is 0 (alias for current).
2373 *---------------------------------------------------------------------------
2374 */
2375struct thread_entry * thread_id_entry(unsigned int thread_id)
2376{
2377 return (thread_id == THREAD_ID_CURRENT) ?
2378 cores[CURRENT_CORE].running :
2379 &threads[thread_id & THREAD_ID_SLOT_MASK];
2380}
2352 2381
2353/*--------------------------------------------------------------------------- 2382/*---------------------------------------------------------------------------
2354 * Place the current core in idle mode - woken up on interrupt or wake 2383 * Place the current core in idle mode - woken up on interrupt or wake
@@ -2369,11 +2398,11 @@ void core_idle(void)
2369 * Return ID if context area could be allocated, else NULL. 2398 * Return ID if context area could be allocated, else NULL.
2370 *--------------------------------------------------------------------------- 2399 *---------------------------------------------------------------------------
2371 */ 2400 */
2372struct thread_entry* 2401unsigned int create_thread(void (*function)(void),
2373 create_thread(void (*function)(void), void* stack, size_t stack_size, 2402 void* stack, size_t stack_size,
2374 unsigned flags, const char *name 2403 unsigned flags, const char *name
2375 IF_PRIO(, int priority) 2404 IF_PRIO(, int priority)
2376 IF_COP(, unsigned int core)) 2405 IF_COP(, unsigned int core))
2377{ 2406{
2378 unsigned int i; 2407 unsigned int i;
2379 unsigned int stack_words; 2408 unsigned int stack_words;
@@ -2385,7 +2414,7 @@ struct thread_entry*
2385 thread = find_empty_thread_slot(); 2414 thread = find_empty_thread_slot();
2386 if (thread == NULL) 2415 if (thread == NULL)
2387 { 2416 {
2388 return NULL; 2417 return 0;
2389 } 2418 }
2390 2419
2391 oldlevel = disable_irq_save(); 2420 oldlevel = disable_irq_save();
@@ -2443,15 +2472,15 @@ struct thread_entry*
2443 THREAD_STARTUP_INIT(core, thread, function); 2472 THREAD_STARTUP_INIT(core, thread, function);
2444 2473
2445 thread->state = state; 2474 thread->state = state;
2475 i = thread->id; /* Snapshot while locked */
2446 2476
2447 if (state == STATE_RUNNING) 2477 if (state == STATE_RUNNING)
2448 core_schedule_wakeup(thread); 2478 core_schedule_wakeup(thread);
2449 2479
2450 UNLOCK_THREAD(thread); 2480 UNLOCK_THREAD(thread);
2451
2452 restore_irq(oldlevel); 2481 restore_irq(oldlevel);
2453 2482
2454 return thread; 2483 return i;
2455} 2484}
2456 2485
2457#ifdef HAVE_SCHEDULER_BOOSTCTRL 2486#ifdef HAVE_SCHEDULER_BOOSTCTRL
@@ -2489,18 +2518,17 @@ void cancel_cpu_boost(void)
2489 * Parameter is the ID as returned from create_thread(). 2518 * Parameter is the ID as returned from create_thread().
2490 *--------------------------------------------------------------------------- 2519 *---------------------------------------------------------------------------
2491 */ 2520 */
2492void thread_wait(struct thread_entry *thread) 2521void thread_wait(unsigned int thread_id)
2493{ 2522{
2494 struct thread_entry *current = cores[CURRENT_CORE].running; 2523 struct thread_entry *current = cores[CURRENT_CORE].running;
2495 2524 struct thread_entry *thread = thread_id_entry(thread_id);
2496 if (thread == NULL)
2497 thread = current;
2498 2525
2499 /* Lock thread-as-waitable-object lock */ 2526 /* Lock thread-as-waitable-object lock */
2500 corelock_lock(&thread->waiter_cl); 2527 corelock_lock(&thread->waiter_cl);
2501 2528
2502 /* Be sure it hasn't been killed yet */ 2529 /* Be sure it hasn't been killed yet */
2503 if (thread->state != STATE_KILLED) 2530 if (thread_id == THREAD_ID_CURRENT ||
2531 (thread->id == thread_id && thread->state != STATE_KILLED))
2504 { 2532 {
2505 IF_COP( current->obj_cl = &thread->waiter_cl; ) 2533 IF_COP( current->obj_cl = &thread->waiter_cl; )
2506 current->bqp = &thread->queue; 2534 current->bqp = &thread->queue;
@@ -2538,9 +2566,10 @@ void thread_exit(void)
2538 if (current->name == THREAD_DESTRUCT) 2566 if (current->name == THREAD_DESTRUCT)
2539 { 2567 {
2540 /* Thread being killed - become a waiter */ 2568 /* Thread being killed - become a waiter */
2569 unsigned int id = current->id;
2541 UNLOCK_THREAD(current); 2570 UNLOCK_THREAD(current);
2542 corelock_unlock(&current->waiter_cl); 2571 corelock_unlock(&current->waiter_cl);
2543 thread_wait(current); 2572 thread_wait(id);
2544 THREAD_PANICF("thread_exit->WK:*R", current); 2573 THREAD_PANICF("thread_exit->WK:*R", current);
2545 } 2574 }
2546#endif 2575#endif
@@ -2568,7 +2597,13 @@ void thread_exit(void)
2568 } 2597 }
2569 2598
2570 flush_icache(); 2599 flush_icache();
2600
2601 /* At this point, this thread isn't using resources allocated for
2602 * execution except the slot itself. */
2571#endif 2603#endif
2604
2605 /* Update ID for this slot */
2606 new_thread_id(current->id, current);
2572 current->name = NULL; 2607 current->name = NULL;
2573 2608
2574 /* Signal this thread */ 2609 /* Signal this thread */
@@ -2593,7 +2628,7 @@ void thread_exit(void)
2593 * leave various objects in an undefined state. 2628 * leave various objects in an undefined state.
2594 *--------------------------------------------------------------------------- 2629 *---------------------------------------------------------------------------
2595 */ 2630 */
2596void remove_thread(struct thread_entry *thread) 2631void remove_thread(unsigned int thread_id)
2597{ 2632{
2598#if NUM_CORES > 1 2633#if NUM_CORES > 1
2599 /* core is not constant here because of core switching */ 2634 /* core is not constant here because of core switching */
@@ -2604,13 +2639,11 @@ void remove_thread(struct thread_entry *thread)
2604 const unsigned int core = CURRENT_CORE; 2639 const unsigned int core = CURRENT_CORE;
2605#endif 2640#endif
2606 struct thread_entry *current = cores[core].running; 2641 struct thread_entry *current = cores[core].running;
2642 struct thread_entry *thread = thread_id_entry(thread_id);
2607 2643
2608 unsigned state; 2644 unsigned state;
2609 int oldlevel; 2645 int oldlevel;
2610 2646
2611 if (thread == NULL)
2612 thread = current;
2613
2614 if (thread == current) 2647 if (thread == current)
2615 thread_exit(); /* Current thread - do normal exit */ 2648 thread_exit(); /* Current thread - do normal exit */
2616 2649
@@ -2621,10 +2654,8 @@ void remove_thread(struct thread_entry *thread)
2621 2654
2622 state = thread->state; 2655 state = thread->state;
2623 2656
2624 if (state == STATE_KILLED) 2657 if (thread->id != thread_id || state == STATE_KILLED)
2625 {
2626 goto thread_killed; 2658 goto thread_killed;
2627 }
2628 2659
2629#if NUM_CORES > 1 2660#if NUM_CORES > 1
2630 if (thread->name == THREAD_DESTRUCT) 2661 if (thread->name == THREAD_DESTRUCT)
@@ -2633,7 +2664,7 @@ void remove_thread(struct thread_entry *thread)
2633 UNLOCK_THREAD(thread); 2664 UNLOCK_THREAD(thread);
2634 corelock_unlock(&thread->waiter_cl); 2665 corelock_unlock(&thread->waiter_cl);
2635 restore_irq(oldlevel); 2666 restore_irq(oldlevel);
2636 thread_wait(thread); 2667 thread_wait(thread_id);
2637 return; 2668 return;
2638 } 2669 }
2639 2670
@@ -2741,6 +2772,7 @@ IF_COP( retry_state: )
2741 /* Otherwise thread is frozen and hasn't run yet */ 2772 /* Otherwise thread is frozen and hasn't run yet */
2742 } 2773 }
2743 2774
2775 new_thread_id(thread_id, thread);
2744 thread->state = STATE_KILLED; 2776 thread->state = STATE_KILLED;
2745 2777
2746 /* If thread was waiting on itself, it will have been removed above. 2778 /* If thread was waiting on itself, it will have been removed above.
@@ -2773,17 +2805,15 @@ thread_killed: /* Thread was already killed */
2773 * needed inheritance changes also may happen. 2805 * needed inheritance changes also may happen.
2774 *--------------------------------------------------------------------------- 2806 *---------------------------------------------------------------------------
2775 */ 2807 */
2776int thread_set_priority(struct thread_entry *thread, int priority) 2808int thread_set_priority(unsigned int thread_id, int priority)
2777{ 2809{
2778 int old_base_priority = -1; 2810 int old_base_priority = -1;
2811 struct thread_entry *thread = thread_id_entry(thread_id);
2779 2812
2780 /* A little safety measure */ 2813 /* A little safety measure */
2781 if (priority < HIGHEST_PRIORITY || priority > LOWEST_PRIORITY) 2814 if (priority < HIGHEST_PRIORITY || priority > LOWEST_PRIORITY)
2782 return -1; 2815 return -1;
2783 2816
2784 if (thread == NULL)
2785 thread = cores[CURRENT_CORE].running;
2786
2787 /* Thread could be on any list and therefore on an interrupt accessible 2817 /* Thread could be on any list and therefore on an interrupt accessible
2788 one - disable interrupts */ 2818 one - disable interrupts */
2789 int oldlevel = disable_irq_save(); 2819 int oldlevel = disable_irq_save();
@@ -2791,7 +2821,8 @@ int thread_set_priority(struct thread_entry *thread, int priority)
2791 LOCK_THREAD(thread); 2821 LOCK_THREAD(thread);
2792 2822
2793 /* Make sure it's not killed */ 2823 /* Make sure it's not killed */
2794 if (thread->state != STATE_KILLED) 2824 if (thread_id == THREAD_ID_CURRENT ||
2825 (thread->id == thread_id && thread->state != STATE_KILLED))
2795 { 2826 {
2796 int old_priority = thread->priority; 2827 int old_priority = thread->priority;
2797 2828
@@ -2908,13 +2939,19 @@ int thread_set_priority(struct thread_entry *thread, int priority)
2908 * Returns the current base priority for a thread. 2939 * Returns the current base priority for a thread.
2909 *--------------------------------------------------------------------------- 2940 *---------------------------------------------------------------------------
2910 */ 2941 */
2911int thread_get_priority(struct thread_entry *thread) 2942int thread_get_priority(unsigned int thread_id)
2912{ 2943{
2913 /* Simple, quick probe. */ 2944 struct thread_entry *thread = thread_id_entry(thread_id);
2914 if (thread == NULL) 2945 int base_priority = thread->base_priority;
2915 thread = cores[CURRENT_CORE].running;
2916 2946
2917 return thread->base_priority; 2947 /* Simply check without locking slot. It may or may not be valid by the
2948 * time the function returns anyway. If all tests pass, it is the
2949 * correct value for when it was valid. */
2950 if (thread_id != THREAD_ID_CURRENT &&
2951 (thread->id != thread_id || thread->state == STATE_KILLED))
2952 base_priority = -1;
2953
2954 return base_priority;
2918} 2955}
2919#endif /* HAVE_PRIORITY_SCHEDULING */ 2956#endif /* HAVE_PRIORITY_SCHEDULING */
2920 2957
@@ -2924,12 +2961,16 @@ int thread_get_priority(struct thread_entry *thread)
2924 * virtue of the slot having a state of STATE_FROZEN. 2961 * virtue of the slot having a state of STATE_FROZEN.
2925 *--------------------------------------------------------------------------- 2962 *---------------------------------------------------------------------------
2926 */ 2963 */
2927void thread_thaw(struct thread_entry *thread) 2964void thread_thaw(unsigned int thread_id)
2928{ 2965{
2966 struct thread_entry *thread = thread_id_entry(thread_id);
2929 int oldlevel = disable_irq_save(); 2967 int oldlevel = disable_irq_save();
2968
2930 LOCK_THREAD(thread); 2969 LOCK_THREAD(thread);
2931 2970
2932 if (thread->state == STATE_FROZEN) 2971 /* If thread is the current one, it cannot be frozen, therefore
2972 * there is no need to check that. */
2973 if (thread->id == thread_id && thread->state == STATE_FROZEN)
2933 core_schedule_wakeup(thread); 2974 core_schedule_wakeup(thread);
2934 2975
2935 UNLOCK_THREAD(thread); 2976 UNLOCK_THREAD(thread);
@@ -2940,9 +2981,9 @@ void thread_thaw(struct thread_entry *thread)
2940 * Return the ID of the currently executing thread. 2981 * Return the ID of the currently executing thread.
2941 *--------------------------------------------------------------------------- 2982 *---------------------------------------------------------------------------
2942 */ 2983 */
2943struct thread_entry * thread_get_current(void) 2984unsigned int thread_get_current(void)
2944{ 2985{
2945 return cores[CURRENT_CORE].running; 2986 return cores[CURRENT_CORE].running->id;
2946} 2987}
2947 2988
2948#if NUM_CORES > 1 2989#if NUM_CORES > 1
@@ -2967,9 +3008,10 @@ unsigned int switch_core(unsigned int new_core)
2967 if (current->name == THREAD_DESTRUCT) 3008 if (current->name == THREAD_DESTRUCT)
2968 { 3009 {
2969 /* Thread being killed - deactivate and let process complete */ 3010 /* Thread being killed - deactivate and let process complete */
3011 unsigned int id = current->id;
2970 UNLOCK_THREAD(current); 3012 UNLOCK_THREAD(current);
2971 restore_irq(oldlevel); 3013 restore_irq(oldlevel);
2972 thread_wait(current); 3014 thread_wait(id);
2973 /* Should never be reached */ 3015 /* Should never be reached */
2974 THREAD_PANICF("switch_core->D:*R", current); 3016 THREAD_PANICF("switch_core->D:*R", current);
2975 } 3017 }
@@ -3034,6 +3076,19 @@ void init_threads(void)
3034 const unsigned int core = CURRENT_CORE; 3076 const unsigned int core = CURRENT_CORE;
3035 struct thread_entry *thread; 3077 struct thread_entry *thread;
3036 3078
3079 if (core == CPU)
3080 {
3081 /* Initialize core locks and IDs in all slots */
3082 int n;
3083 for (n = 0; n < MAXTHREADS; n++)
3084 {
3085 thread = &threads[n];
3086 corelock_init(&thread->waiter_cl);
3087 corelock_init(&thread->slot_cl);
3088 thread->id = THREAD_ID_INIT(n);
3089 }
3090 }
3091
3037 /* CPU will initialize first and then sleep */ 3092 /* CPU will initialize first and then sleep */
3038 thread = find_empty_thread_slot(); 3093 thread = find_empty_thread_slot();
3039 3094
@@ -3060,8 +3115,6 @@ void init_threads(void)
3060 thread->priority = PRIORITY_USER_INTERFACE; 3115 thread->priority = PRIORITY_USER_INTERFACE;
3061 rtr_add_entry(core, PRIORITY_USER_INTERFACE); 3116 rtr_add_entry(core, PRIORITY_USER_INTERFACE);
3062#endif 3117#endif
3063 corelock_init(&thread->waiter_cl);
3064 corelock_init(&thread->slot_cl);
3065 3118
3066 add_to_list_l(&cores[core].running, thread); 3119 add_to_list_l(&cores[core].running, thread);
3067 3120
@@ -3070,6 +3123,7 @@ void init_threads(void)
3070 thread->stack = stackbegin; 3123 thread->stack = stackbegin;
3071 thread->stack_size = (uintptr_t)stackend - (uintptr_t)stackbegin; 3124 thread->stack_size = (uintptr_t)stackend - (uintptr_t)stackbegin;
3072#if NUM_CORES > 1 /* This code path will not be run on single core targets */ 3125#if NUM_CORES > 1 /* This code path will not be run on single core targets */
3126 /* Initialize all locking for the slots */
3073 /* Wait for other processors to finish their inits since create_thread 3127 /* Wait for other processors to finish their inits since create_thread
3074 * isn't safe to call until the kernel inits are done. The first 3128 * isn't safe to call until the kernel inits are done. The first
3075 * threads created in the system must of course be created by CPU. */ 3129 * threads created in the system must of course be created by CPU. */
diff --git a/firmware/usb.c b/firmware/usb.c
index f9bfbc4dbf..2bff53e5d6 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -78,7 +78,7 @@ static int usb_mmc_countdown = 0;
78#ifdef USB_FULL_INIT 78#ifdef USB_FULL_INIT
79static long usb_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; 79static long usb_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)];
80static const char usb_thread_name[] = "usb"; 80static const char usb_thread_name[] = "usb";
81static struct thread_entry *usb_thread_entry; 81static unsigned int usb_thread_entry = 0;
82#endif 82#endif
83static struct event_queue usb_queue; 83static struct event_queue usb_queue;
84static int last_usb_status; 84static int last_usb_status;
@@ -539,10 +539,10 @@ void usb_start_monitoring(void)
539#ifdef USB_DRIVER_CLOSE 539#ifdef USB_DRIVER_CLOSE
540void usb_close(void) 540void usb_close(void)
541{ 541{
542 struct thread_entry *thread = usb_thread_entry; 542 uintptr_t thread = usb_thread_entry;
543 usb_thread_entry = NULL; 543 usb_thread_entry = 0;
544 544
545 if (thread == NULL) 545 if (thread == 0)
546 return; 546 return;
547 547
548 tick_remove_task(usb_tick); 548 tick_remove_task(usb_tick);
diff --git a/uisimulator/sdl/thread-sdl.c b/uisimulator/sdl/thread-sdl.c
index 905a017ee0..ab1086dd7d 100644
--- a/uisimulator/sdl/thread-sdl.c
+++ b/uisimulator/sdl/thread-sdl.c
@@ -93,6 +93,38 @@ void thread_sdl_shutdown(void)
93 SDL_DestroyMutex(m); 93 SDL_DestroyMutex(m);
94} 94}
95 95
96static void new_thread_id(unsigned int slot_num,
97 struct thread_entry *thread)
98{
99 unsigned int version =
100 (thread->id + (1u << THREAD_ID_VERSION_SHIFT))
101 & THREAD_ID_VERSION_MASK;
102
103 if (version == 0)
104 version = 1u << THREAD_ID_VERSION_SHIFT;
105
106 thread->id = version | (slot_num & THREAD_ID_SLOT_MASK);
107}
108
109static struct thread_entry * find_empty_thread_slot(void)
110{
111 struct thread_entry *thread = NULL;
112 int n;
113
114 for (n = 0; n < MAXTHREADS; n++)
115 {
116 int state = threads[n].state;
117
118 if (state == STATE_KILLED)
119 {
120 thread = &threads[n];
121 break;
122 }
123 }
124
125 return thread;
126}
127
96/* Do main thread creation in this file scope to avoid the need to double- 128/* Do main thread creation in this file scope to avoid the need to double-
97 return to a prior call-level which would be unaware of the fact setjmp 129 return to a prior call-level which would be unaware of the fact setjmp
98 was used */ 130 was used */
@@ -119,6 +151,8 @@ static int thread_sdl_app_main(void *param)
119bool thread_sdl_init(void *param) 151bool thread_sdl_init(void *param)
120{ 152{
121 struct thread_entry *thread; 153 struct thread_entry *thread;
154 int n;
155
122 memset(cores, 0, sizeof(cores)); 156 memset(cores, 0, sizeof(cores));
123 memset(threads, 0, sizeof(threads)); 157 memset(threads, 0, sizeof(threads));
124 158
@@ -130,6 +164,10 @@ bool thread_sdl_init(void *param)
130 return false; 164 return false;
131 } 165 }
132 166
167 /* Initialize all IDs */
168 for (n = 0; n < MAXTHREADS; n++)
169 threads[n].id = THREAD_ID_INIT(n);
170
133 /* Slot 0 is reserved for the main thread - initialize it here and 171 /* Slot 0 is reserved for the main thread - initialize it here and
134 then create the SDL thread - it is possible to have a quick, early 172 then create the SDL thread - it is possible to have a quick, early
135 shutdown try to access the structure. */ 173 shutdown try to access the structure. */
@@ -179,23 +217,11 @@ void * thread_sdl_thread_unlock(void)
179 return current; 217 return current;
180} 218}
181 219
182static struct thread_entry * find_empty_thread_slot(void) 220struct thread_entry * thread_id_entry(unsigned int thread_id)
183{ 221{
184 struct thread_entry *thread = NULL; 222 return (thread_id == THREAD_ID_CURRENT) ?
185 int n; 223 cores[CURRENT_CORE].running :
186 224 &threads[thread_id & THREAD_ID_SLOT_MASK];
187 for (n = 0; n < MAXTHREADS; n++)
188 {
189 int state = threads[n].state;
190
191 if (state == STATE_KILLED)
192 {
193 thread = &threads[n];
194 break;
195 }
196 }
197
198 return thread;
199} 225}
200 226
201static void add_to_list_l(struct thread_entry **list, 227static void add_to_list_l(struct thread_entry **list,
@@ -239,9 +265,9 @@ static void remove_from_list_l(struct thread_entry **list,
239 thread->l.next->l.prev = thread->l.prev; 265 thread->l.next->l.prev = thread->l.prev;
240} 266}
241 267
242struct thread_entry *thread_get_current(void) 268unsigned int thread_get_current(void)
243{ 269{
244 return cores[CURRENT_CORE].running; 270 return cores[CURRENT_CORE].running->id;
245} 271}
246 272
247void switch_thread(void) 273void switch_thread(void)
@@ -389,9 +415,11 @@ unsigned int thread_queue_wake(struct thread_entry **list)
389 return result; 415 return result;
390} 416}
391 417
392void thread_thaw(struct thread_entry *thread) 418void thread_thaw(unsigned int thread_id)
393{ 419{
394 if (thread->state == STATE_FROZEN) 420 struct thread_entry *thread = thread_id_entry(thread_id);
421
422 if (thread->id == thread_id && thread->state == STATE_FROZEN)
395 { 423 {
396 thread->state = STATE_RUNNING; 424 thread->state = STATE_RUNNING;
397 SDL_SemPost(thread->context.s); 425 SDL_SemPost(thread->context.s);
@@ -441,9 +469,9 @@ int runthread(void *data)
441 return 0; 469 return 0;
442} 470}
443 471
444struct thread_entry* 472unsigned int create_thread(void (*function)(void),
445 create_thread(void (*function)(void), void* stack, size_t stack_size, 473 void* stack, size_t stack_size,
446 unsigned flags, const char *name) 474 unsigned flags, const char *name)
447{ 475{
448 struct thread_entry *thread; 476 struct thread_entry *thread;
449 SDL_Thread* t; 477 SDL_Thread* t;
@@ -455,14 +483,14 @@ struct thread_entry*
455 if (thread == NULL) 483 if (thread == NULL)
456 { 484 {
457 DEBUGF("Failed to find thread slot\n"); 485 DEBUGF("Failed to find thread slot\n");
458 return NULL; 486 return 0;
459 } 487 }
460 488
461 s = SDL_CreateSemaphore(0); 489 s = SDL_CreateSemaphore(0);
462 if (s == NULL) 490 if (s == NULL)
463 { 491 {
464 DEBUGF("Failed to create semaphore\n"); 492 DEBUGF("Failed to create semaphore\n");
465 return NULL; 493 return 0;
466 } 494 }
467 495
468 t = SDL_CreateThread(runthread, thread); 496 t = SDL_CreateThread(runthread, thread);
@@ -470,7 +498,7 @@ struct thread_entry*
470 { 498 {
471 DEBUGF("Failed to create SDL thread\n"); 499 DEBUGF("Failed to create SDL thread\n");
472 SDL_DestroySemaphore(s); 500 SDL_DestroySemaphore(s);
473 return NULL; 501 return 0;
474 } 502 }
475 503
476 thread->stack = stack; 504 thread->stack = stack;
@@ -485,7 +513,7 @@ struct thread_entry*
485 THREAD_SDL_DEBUGF("New Thread: %d (%s)\n", 513 THREAD_SDL_DEBUGF("New Thread: %d (%s)\n",
486 thread - threads, THREAD_SDL_GET_NAME(thread)); 514 thread - threads, THREAD_SDL_GET_NAME(thread));
487 515
488 return thread; 516 return thread->id;
489} 517}
490 518
491void init_threads(void) 519void init_threads(void)
@@ -501,18 +529,22 @@ void init_threads(void)
501 0, THREAD_SDL_GET_NAME(&threads[0])); 529 0, THREAD_SDL_GET_NAME(&threads[0]));
502} 530}
503 531
504void remove_thread(struct thread_entry *thread) 532#ifndef ALLOW_REMOVE_THREAD
533static void remove_thread(unsigned int thread_id)
534#else
535void remove_thread(unsigned int thread_id)
536#endif
505{ 537{
506 struct thread_entry *current = cores[CURRENT_CORE].running; 538 struct thread_entry *current = cores[CURRENT_CORE].running;
539 struct thread_entry *thread = thread_id_entry(thread_id);
540
507 SDL_Thread *t; 541 SDL_Thread *t;
508 SDL_sem *s; 542 SDL_sem *s;
509 543
510 int oldlevel = disable_irq_save(); 544 if (thread_id != THREAD_ID_CURRENT && thread->id != thread_id)
545 return;
511 546
512 if (thread == NULL) 547 int oldlevel = disable_irq_save();
513 {
514 thread = current;
515 }
516 548
517 t = thread->context.t; 549 t = thread->context.t;
518 s = thread->context.s; 550 s = thread->context.s;
@@ -540,6 +572,7 @@ void remove_thread(struct thread_entry *thread)
540 THREAD_SDL_DEBUGF("Removing thread: %d (%s)\n", 572 THREAD_SDL_DEBUGF("Removing thread: %d (%s)\n",
541 thread - threads, THREAD_SDL_GET_NAME(thread)); 573 thread - threads, THREAD_SDL_GET_NAME(thread));
542 574
575 new_thread_id(thread->id, thread);
543 thread->state = STATE_KILLED; 576 thread->state = STATE_KILLED;
544 thread_queue_wake(&thread->queue); 577 thread_queue_wake(&thread->queue);
545 578
@@ -559,17 +592,16 @@ void remove_thread(struct thread_entry *thread)
559 592
560void thread_exit(void) 593void thread_exit(void)
561{ 594{
562 remove_thread(NULL); 595 remove_thread(THREAD_ID_CURRENT);
563} 596}
564 597
565void thread_wait(struct thread_entry *thread) 598void thread_wait(unsigned int thread_id)
566{ 599{
567 struct thread_entry *current = cores[CURRENT_CORE].running; 600 struct thread_entry *current = cores[CURRENT_CORE].running;
601 struct thread_entry *thread = thread_id_entry(thread_id);
568 602
569 if (thread == NULL) 603 if (thread_id == THREAD_ID_CURRENT ||
570 thread = current; 604 (thread->id == thread_id && thread->state != STATE_KILLED))
571
572 if (thread->state != STATE_KILLED)
573 { 605 {
574 current->bqp = &thread->queue; 606 current->bqp = &thread->queue;
575 block_thread(current); 607 block_thread(current);
@@ -583,11 +615,6 @@ int thread_stack_usage(const struct thread_entry *thread)
583 (void)thread; 615 (void)thread;
584} 616}
585 617
586unsigned thread_get_status(const struct thread_entry *thread)
587{
588 return thread->state;
589}
590
591/* Return name if one or ID if none */ 618/* Return name if one or ID if none */
592void thread_get_name(char *buffer, int size, 619void thread_get_name(char *buffer, int size,
593 struct thread_entry *thread) 620 struct thread_entry *thread)