diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2008-12-10 08:57:10 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2008-12-10 08:57:10 +0000 |
commit | 8cfbd3604fac14f629244e521ad24ffa9938c790 (patch) | |
tree | 16dc096519b8b537bb7d4b73e0c97f5f33ee752b | |
parent | 40ff47c7eea41ac893d7af5c5b97ace52a5ffade (diff) | |
download | rockbox-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
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 { | |||
184 | static void buffering_thread(void); | 184 | static void buffering_thread(void); |
185 | static long buffering_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)]; | 185 | static long buffering_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)]; |
186 | static const char buffering_thread_name[] = "buffering"; | 186 | static const char buffering_thread_name[] = "buffering"; |
187 | static struct thread_entry *buffering_thread_p; | 187 | static unsigned int buffering_thread_id = 0; |
188 | static struct event_queue buffering_queue; | 188 | static struct event_queue buffering_queue; |
189 | static struct queue_sender_list buffering_queue_sender_list; | 189 | static 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 */ |
93 | enum codec_status { | 93 | enum 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) | |||
200 | static int mad_synth_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)/2] IBSS_ATTR; | 200 | static int mad_synth_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)/2] IBSS_ATTR; |
201 | 201 | ||
202 | static const unsigned char * const mad_synth_thread_name = "mp3dec"; | 202 | static const unsigned char * const mad_synth_thread_name = "mp3dec"; |
203 | static struct thread_entry *mad_synth_thread_p; | 203 | static unsigned int mad_synth_thread_id = 0; |
204 | 204 | ||
205 | 205 | ||
206 | static void mad_synth_thread(void) | 206 | static 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 | ||
199 | static const unsigned char * const spc_emu_thread_name = "spc emu"; | 199 | static const unsigned char * const spc_emu_thread_name = "spc emu"; |
200 | static struct thread_entry *emu_thread_p; | 200 | static unsigned int emu_thread_id = 0; |
201 | 201 | ||
202 | enum | 202 | enum |
203 | { | 203 | { |
@@ -352,11 +352,11 @@ static void spc_emu_thread(void) | |||
352 | 352 | ||
353 | static bool spc_emu_start(void) | 353 | static 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 | ||
383 | static inline void spc_emu_quit(void) | 383 | static 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; | |||
115 | static int codec_thread_priority = PRIORITY_PLAYBACK; | 115 | static int codec_thread_priority = PRIORITY_PLAYBACK; |
116 | #endif | 116 | #endif |
117 | 117 | ||
118 | extern struct thread_entry *codec_thread_p; | 118 | extern 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; | |||
299 | static long codec_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)] | 299 | static long codec_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)] |
300 | IBSS_ATTR; | 300 | IBSS_ATTR; |
301 | static const char codec_thread_name[] = "codec"; | 301 | static const char codec_thread_name[] = "codec"; |
302 | struct thread_entry *codec_thread_p; /* For modifying thread priority later. */ | 302 | unsigned int codec_thread_id; /* For modifying thread priority later. */ |
303 | 303 | ||
304 | /* PCM buffer messaging */ | 304 | /* PCM buffer messaging */ |
305 | static struct event_queue pcmbuf_queue SHAREDBSS_ATTR; | 305 | static struct event_queue pcmbuf_queue SHAREDBSS_ATTR; |
@@ -2499,7 +2499,7 @@ static void audio_thread(void) | |||
2499 | */ | 2499 | */ |
2500 | void audio_init(void) | 2500 | void 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 | ||
626 | int plugin_load(const char* plugin, const void* parameter) | 626 | int 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 */ |
142 | enum plugin_status { | 142 | enum 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 | ||
212 | static const struct plugin_api* rb; /* here is the global API struct pointer */ | 212 | static 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 | ||
219 | static struct thread_entry *thread_id; | 219 | static unsigned int thread_id; |
220 | static struct event_queue thread_q; | 220 | static struct event_queue thread_q; |
221 | static bool in_usb_mode; | 221 | static bool in_usb_mode; |
222 | static unsigned int buf_idx; | 222 | static 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 */ |
745 | void audio_thread_exit(void) | 745 | void 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 | ||
836 | bool disk_buf_init(void) | 836 | bool 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 | ||
905 | void disk_buf_exit(void) | 905 | void 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 */ |
63 | struct disk_buf | 63 | struct 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 */ |
909 | int stream_open(const char *filename) | 909 | int 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' */ |
917 | int stream_play(void) | 917 | int 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 */ |
925 | int stream_pause(void) | 925 | int 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 */ |
933 | int stream_resume(void) | 933 | int 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 */ |
941 | int stream_stop(void) | 941 | int 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 */ |
969 | int stream_close(void) | 969 | int 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 */ |
28 | struct stream_mgr | 28 | struct 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 | |||
45 | struct stream | 45 | struct 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 */ |
1023 | void video_thread_exit(void) | 1023 | void 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 | ||
219 | static int empty_slide_hid; | 219 | static int empty_slide_hid; |
220 | 220 | ||
221 | struct thread_entry *thread_id; | 221 | unsigned int thread_id; |
222 | struct event_queue thread_q; | 222 | struct event_queue thread_q; |
223 | 223 | ||
224 | static char tmp_path_name[MAX_PATH]; | 224 | static 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 | ||
40 | static int gen_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)] IBSS_ATTR; | 40 | static int gen_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)] IBSS_ATTR; |
41 | static bool gen_quit IBSS_ATTR; | 41 | static bool gen_quit IBSS_ATTR; |
42 | static struct thread_entry *gen_thread_p; | 42 | static 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 | ||
40 | extern struct thread_entry *codec_thread_p; | 40 | extern uintptr_t codec_thread_id; |
41 | 41 | ||
42 | /** General recording state **/ | 42 | /** General recording state **/ |
43 | static bool is_recording; /* We are recording */ | 43 | static bool is_recording; /* We are recording */ |
@@ -220,7 +220,7 @@ static struct event_queue pcmrec_queue SHAREDBSS_ATTR; | |||
220 | static struct queue_sender_list pcmrec_queue_send SHAREDBSS_ATTR; | 220 | static struct queue_sender_list pcmrec_queue_send SHAREDBSS_ATTR; |
221 | static long pcmrec_stack[3*DEFAULT_STACK_SIZE/sizeof(long)]; | 221 | static long pcmrec_stack[3*DEFAULT_STACK_SIZE/sizeof(long)]; |
222 | static const char pcmrec_thread_name[] = "pcmrec"; | 222 | static const char pcmrec_thread_name[] = "pcmrec"; |
223 | static struct thread_entry *pcmrec_thread_p; | 223 | static unsigned int pcmrec_thread_id = 0; |
224 | 224 | ||
225 | static void pcmrec_thread(void); | 225 | static void pcmrec_thread(void); |
226 | 226 | ||
@@ -365,12 +365,12 @@ unsigned long pcm_rec_sample_rate(void) | |||
365 | void pcm_rec_init(void) | 365 | void 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 */ |
57 | static struct thread_entry *voice_thread_p = NULL; | 57 | static unsigned int voice_thread_id = 0; |
58 | static long voice_stack[0x7c0/sizeof(long)] IBSS_ATTR_VOICE_STACK; | 58 | static long voice_stack[0x7c0/sizeof(long)] IBSS_ATTR_VOICE_STACK; |
59 | static const char voice_thread_name[] = "voice"; | 59 | static 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 */ |
446 | void voice_thread_resume(void) | 446 | void 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 */ |
454 | void voice_thread_set_priority(int priority) | 454 | void 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)]; | |||
130 | static const char backlight_thread_name[] = "backlight"; | 130 | static const char backlight_thread_name[] = "backlight"; |
131 | static struct event_queue backlight_queue; | 131 | static struct event_queue backlight_queue; |
132 | #ifdef BACKLIGHT_DRIVER_CLOSE | 132 | #ifdef BACKLIGHT_DRIVER_CLOSE |
133 | static struct thread_entry *backlight_thread_p = NULL; | 133 | static unsigned int backlight_thread_id = 0; |
134 | #endif | 134 | #endif |
135 | 135 | ||
136 | static int backlight_timer SHAREDBSS_ATTR; | 136 | static 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 |
757 | void backlight_close(void) | 757 | void 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 |
74 | static struct thread_entry *ata_thread_p = NULL; | 74 | static 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 | ||
95 | static void ata_lock_lock(struct ata_lock *l) | 95 | static 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 |
1371 | void ata_close(void) | 1372 | void 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 |
262 | extern void queue_enable_queue_send(struct event_queue *q, | 262 | extern 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); |
265 | extern intptr_t queue_send(struct event_queue *q, long id, intptr_t data); | 265 | extern intptr_t queue_send(struct event_queue *q, long id, intptr_t data); |
266 | extern void queue_reply(struct event_queue *q, intptr_t retval); | 266 | extern void queue_reply(struct event_queue *q, intptr_t retval); |
267 | extern bool queue_in_queue_send(struct event_queue *q); | 267 | extern 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 */ |
478 | struct thread_entry* | 486 | unsigned 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 */ | ||
501 | struct 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. */ |
494 | void thread_thaw(struct thread_entry *thread); | 504 | void thread_thaw(unsigned int thread_id); |
495 | /* Wait for a thread to exit */ | 505 | /* Wait for a thread to exit */ |
496 | void thread_wait(struct thread_entry *thread); | 506 | void thread_wait(unsigned int thread_id); |
497 | /* Exit the current thread */ | 507 | /* Exit the current thread */ |
498 | void thread_exit(void); | 508 | void 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 */ |
502 | void remove_thread(struct thread_entry *thread); | 512 | void 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); | |||
526 | unsigned int wakeup_thread(struct thread_entry **list); | 536 | unsigned int wakeup_thread(struct thread_entry **list); |
527 | 537 | ||
528 | #ifdef HAVE_PRIORITY_SCHEDULING | 538 | #ifdef HAVE_PRIORITY_SCHEDULING |
529 | int thread_set_priority(struct thread_entry *thread, int priority); | 539 | int thread_set_priority(unsigned int thread_id, int priority); |
530 | int thread_get_priority(struct thread_entry *thread); | 540 | int 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 |
533 | unsigned int switch_core(unsigned int new_core); | 543 | unsigned int switch_core(unsigned int new_core); |
534 | #endif | 544 | #endif |
535 | struct thread_entry * thread_get_current(void); | 545 | unsigned int thread_get_current(void); |
536 | 546 | ||
537 | /* Debugging info - only! */ | 547 | /* Debugging info - only! */ |
538 | int thread_stack_usage(const struct thread_entry *thread); | 548 | int 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 | */ |
357 | void queue_enable_queue_send(struct event_queue *q, | 358 | void 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) | |||
914 | void mutex_unlock(struct mutex *m) | 917 | void 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) | |||
990 | void spinlock_unlock(struct spinlock *l) | 993 | void 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 |
71 | static bool pmic_close = false; | 71 | static bool pmic_close = false; |
72 | static struct thread_entry *mc13783_thread_p = NULL; | 72 | static unsigned int mc13783_thread_id = 0; |
73 | #endif | 73 | #endif |
74 | 74 | ||
75 | static void mc13783_interrupt_thread(void) | 75 | static 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 |
160 | void mc13783_close(void) | 160 | void 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 | */ | ||
2322 | static 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 | */ | ||
2375 | struct 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 | */ |
2372 | struct thread_entry* | 2401 | unsigned 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 | */ |
2492 | void thread_wait(struct thread_entry *thread) | 2521 | void 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(¤t->waiter_cl); | 2571 | corelock_unlock(¤t->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 | */ |
2596 | void remove_thread(struct thread_entry *thread) | 2631 | void 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 | */ |
2776 | int thread_set_priority(struct thread_entry *thread, int priority) | 2808 | int 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 | */ |
2911 | int thread_get_priority(struct thread_entry *thread) | 2942 | int 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 | */ |
2927 | void thread_thaw(struct thread_entry *thread) | 2964 | void 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 | */ |
2943 | struct thread_entry * thread_get_current(void) | 2984 | unsigned 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 |
79 | static long usb_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; | 79 | static long usb_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; |
80 | static const char usb_thread_name[] = "usb"; | 80 | static const char usb_thread_name[] = "usb"; |
81 | static struct thread_entry *usb_thread_entry; | 81 | static unsigned int usb_thread_entry = 0; |
82 | #endif | 82 | #endif |
83 | static struct event_queue usb_queue; | 83 | static struct event_queue usb_queue; |
84 | static int last_usb_status; | 84 | static int last_usb_status; |
@@ -539,10 +539,10 @@ void usb_start_monitoring(void) | |||
539 | #ifdef USB_DRIVER_CLOSE | 539 | #ifdef USB_DRIVER_CLOSE |
540 | void usb_close(void) | 540 | void 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 | ||
96 | static 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 | |||
109 | static 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) | |||
119 | bool thread_sdl_init(void *param) | 151 | bool 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 | ||
182 | static struct thread_entry * find_empty_thread_slot(void) | 220 | struct 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 | ||
201 | static void add_to_list_l(struct thread_entry **list, | 227 | static 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 | ||
242 | struct thread_entry *thread_get_current(void) | 268 | unsigned int thread_get_current(void) |
243 | { | 269 | { |
244 | return cores[CURRENT_CORE].running; | 270 | return cores[CURRENT_CORE].running->id; |
245 | } | 271 | } |
246 | 272 | ||
247 | void switch_thread(void) | 273 | void 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 | ||
392 | void thread_thaw(struct thread_entry *thread) | 418 | void 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 | ||
444 | struct thread_entry* | 472 | unsigned 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 | ||
491 | void init_threads(void) | 519 | void 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 | ||
504 | void remove_thread(struct thread_entry *thread) | 532 | #ifndef ALLOW_REMOVE_THREAD |
533 | static void remove_thread(unsigned int thread_id) | ||
534 | #else | ||
535 | void 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 | ||
560 | void thread_exit(void) | 593 | void thread_exit(void) |
561 | { | 594 | { |
562 | remove_thread(NULL); | 595 | remove_thread(THREAD_ID_CURRENT); |
563 | } | 596 | } |
564 | 597 | ||
565 | void thread_wait(struct thread_entry *thread) | 598 | void 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 | ||
586 | unsigned 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 */ |
592 | void thread_get_name(char *buffer, int size, | 619 | void thread_get_name(char *buffer, int size, |
593 | struct thread_entry *thread) | 620 | struct thread_entry *thread) |