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
This commit is contained in:
parent
40ff47c7ee
commit
8cfbd3604f
32 changed files with 329 additions and 234 deletions
|
@ -184,7 +184,7 @@ enum {
|
|||
static void buffering_thread(void);
|
||||
static long buffering_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)];
|
||||
static const char buffering_thread_name[] = "buffering";
|
||||
static struct thread_entry *buffering_thread_p;
|
||||
static unsigned int buffering_thread_id = 0;
|
||||
static struct event_queue buffering_queue;
|
||||
static struct queue_sender_list buffering_queue_sender_list;
|
||||
|
||||
|
@ -1468,13 +1468,13 @@ void buffering_init(void)
|
|||
conf_watermark = BUFFERING_DEFAULT_WATERMARK;
|
||||
|
||||
queue_init(&buffering_queue, true);
|
||||
buffering_thread_p = create_thread( buffering_thread, buffering_stack,
|
||||
buffering_thread_id = create_thread( buffering_thread, buffering_stack,
|
||||
sizeof(buffering_stack), CREATE_THREAD_FROZEN,
|
||||
buffering_thread_name IF_PRIO(, PRIORITY_BUFFERING)
|
||||
IF_COP(, CPU));
|
||||
|
||||
queue_enable_queue_send(&buffering_queue, &buffering_queue_sender_list,
|
||||
buffering_thread_p);
|
||||
buffering_thread_id);
|
||||
}
|
||||
|
||||
/* Initialise the buffering subsystem */
|
||||
|
@ -1501,7 +1501,7 @@ bool buffering_reset(char *buf, size_t buflen)
|
|||
high_watermark = 3*buflen / 4;
|
||||
#endif
|
||||
|
||||
thread_thaw(buffering_thread_p);
|
||||
thread_thaw(buffering_thread_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -82,12 +82,12 @@
|
|||
#define CODEC_ENC_MAGIC 0x52454E43 /* RENC */
|
||||
|
||||
/* increase this every time the api struct changes */
|
||||
#define CODEC_API_VERSION 27
|
||||
#define CODEC_API_VERSION 28
|
||||
|
||||
/* update this to latest version if a change to the api struct breaks
|
||||
backwards compatibility (and please take the opportunity to sort in any
|
||||
new function which are "waiting" at the end of the function table) */
|
||||
#define CODEC_MIN_API_VERSION 27
|
||||
#define CODEC_MIN_API_VERSION 28
|
||||
|
||||
/* codec return codes */
|
||||
enum codec_status {
|
||||
|
@ -164,14 +164,14 @@ struct codec_api {
|
|||
void (*yield)(void);
|
||||
|
||||
#if NUM_CORES > 1
|
||||
struct thread_entry *
|
||||
unsigned int
|
||||
(*create_thread)(void (*function)(void), void* stack,
|
||||
size_t stack_size, unsigned flags, const char *name
|
||||
IF_PRIO(, int priority)
|
||||
IF_COP(, unsigned int core));
|
||||
|
||||
void (*thread_thaw)(struct thread_entry *thread);
|
||||
void (*thread_wait)(struct thread_entry *thread);
|
||||
void (*thread_thaw)(unsigned int thread_id);
|
||||
void (*thread_wait)(unsigned int thread_id);
|
||||
void (*semaphore_init)(struct semaphore *s, int max, int start);
|
||||
void (*semaphore_wait)(struct semaphore *s);
|
||||
void (*semaphore_release)(struct semaphore *s);
|
||||
|
|
|
@ -200,7 +200,7 @@ static void set_elapsed(struct mp3entry* id3)
|
|||
static int mad_synth_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)/2] IBSS_ATTR;
|
||||
|
||||
static const unsigned char * const mad_synth_thread_name = "mp3dec";
|
||||
static struct thread_entry *mad_synth_thread_p;
|
||||
static unsigned int mad_synth_thread_id = 0;
|
||||
|
||||
|
||||
static void mad_synth_thread(void)
|
||||
|
@ -249,14 +249,14 @@ static bool mad_synth_thread_create(void)
|
|||
ci->semaphore_init(&synth_done_sem, 1, 0);
|
||||
ci->semaphore_init(&synth_pending_sem, 1, 0);
|
||||
|
||||
mad_synth_thread_p = ci->create_thread(mad_synth_thread,
|
||||
mad_synth_thread_id = ci->create_thread(mad_synth_thread,
|
||||
mad_synth_thread_stack,
|
||||
sizeof(mad_synth_thread_stack), 0,
|
||||
mad_synth_thread_name
|
||||
IF_PRIO(, PRIORITY_PLAYBACK)
|
||||
IF_COP(, COP));
|
||||
|
||||
if (mad_synth_thread_p == NULL)
|
||||
if (mad_synth_thread_id == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -267,7 +267,7 @@ static void mad_synth_thread_quit(void)
|
|||
/*mop up COP thread*/
|
||||
die=1;
|
||||
ci->semaphore_release(&synth_pending_sem);
|
||||
ci->thread_wait(mad_synth_thread_p);
|
||||
ci->thread_wait(mad_synth_thread_id);
|
||||
invalidate_icache();
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -197,7 +197,7 @@ static int spc_emu_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)]
|
|||
CACHEALIGN_ATTR;
|
||||
|
||||
static const unsigned char * const spc_emu_thread_name = "spc emu";
|
||||
static struct thread_entry *emu_thread_p;
|
||||
static unsigned int emu_thread_id = 0;
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -352,11 +352,11 @@ static void spc_emu_thread(void)
|
|||
|
||||
static bool spc_emu_start(void)
|
||||
{
|
||||
emu_thread_p = ci->create_thread(spc_emu_thread, spc_emu_thread_stack,
|
||||
emu_thread_id = ci->create_thread(spc_emu_thread, spc_emu_thread_stack,
|
||||
sizeof(spc_emu_thread_stack), CREATE_THREAD_FROZEN,
|
||||
spc_emu_thread_name IF_PRIO(, PRIORITY_PLAYBACK), COP);
|
||||
|
||||
if (emu_thread_p == NULL)
|
||||
if (emu_thread_id == 0)
|
||||
return false;
|
||||
|
||||
/* Initialize audio queue as full to prevent emu thread from trying to run the
|
||||
|
@ -368,7 +368,7 @@ static bool spc_emu_start(void)
|
|||
sample_queue.tail = 2;
|
||||
|
||||
/* Start it running */
|
||||
ci->thread_thaw(emu_thread_p);
|
||||
ci->thread_thaw(emu_thread_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -382,10 +382,10 @@ static inline int load_spc_buffer(uint8_t *buf, size_t size)
|
|||
|
||||
static inline void spc_emu_quit(void)
|
||||
{
|
||||
if (emu_thread_p != NULL) {
|
||||
if (emu_thread_id != 0) {
|
||||
emu_thread_send_msg(SPC_EMU_QUIT, 0);
|
||||
/* Wait for emu thread to be killed */
|
||||
ci->thread_wait(emu_thread_p);
|
||||
ci->thread_wait(emu_thread_id);
|
||||
invalidate_icache();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ static bool pcmbuf_flush;
|
|||
static int codec_thread_priority = PRIORITY_PLAYBACK;
|
||||
#endif
|
||||
|
||||
extern struct thread_entry *codec_thread_p;
|
||||
extern uintptr_t codec_thread_id;
|
||||
|
||||
/* Helpful macros for use in conditionals this assumes some of the above
|
||||
* static variable names */
|
||||
|
@ -258,13 +258,13 @@ static void boost_codec_thread(bool boost)
|
|||
if (priority != codec_thread_priority)
|
||||
{
|
||||
codec_thread_priority = priority;
|
||||
thread_set_priority(codec_thread_p, priority);
|
||||
thread_set_priority(codec_thread_id, priority);
|
||||
voice_thread_set_priority(priority);
|
||||
}
|
||||
}
|
||||
else if (codec_thread_priority != PRIORITY_PLAYBACK)
|
||||
{
|
||||
thread_set_priority(codec_thread_p, PRIORITY_PLAYBACK);
|
||||
thread_set_priority(codec_thread_id, PRIORITY_PLAYBACK);
|
||||
voice_thread_set_priority(PRIORITY_PLAYBACK);
|
||||
codec_thread_priority = PRIORITY_PLAYBACK;
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ static void pcmbuf_under_watermark(void)
|
|||
/* Only codec thread initiates boost - voice boosts the cpu when playing
|
||||
a clip */
|
||||
#ifndef SIMULATOR
|
||||
if (thread_get_current() == codec_thread_p)
|
||||
if (thread_get_current() == codec_thread_id)
|
||||
#endif /* SIMULATOR */
|
||||
{
|
||||
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||
|
|
|
@ -299,7 +299,7 @@ static struct queue_sender_list codec_queue_sender_list;
|
|||
static long codec_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)]
|
||||
IBSS_ATTR;
|
||||
static const char codec_thread_name[] = "codec";
|
||||
struct thread_entry *codec_thread_p; /* For modifying thread priority later. */
|
||||
unsigned int codec_thread_id; /* For modifying thread priority later. */
|
||||
|
||||
/* PCM buffer messaging */
|
||||
static struct event_queue pcmbuf_queue SHAREDBSS_ATTR;
|
||||
|
@ -2499,7 +2499,7 @@ static void audio_thread(void)
|
|||
*/
|
||||
void audio_init(void)
|
||||
{
|
||||
struct thread_entry *audio_thread_p;
|
||||
unsigned int audio_thread_id;
|
||||
|
||||
/* Can never do this twice */
|
||||
if (audio_is_initialized)
|
||||
|
@ -2543,22 +2543,22 @@ void audio_init(void)
|
|||
talk first */
|
||||
talk_init();
|
||||
|
||||
codec_thread_p = create_thread(
|
||||
codec_thread_id = create_thread(
|
||||
codec_thread, codec_stack, sizeof(codec_stack),
|
||||
CREATE_THREAD_FROZEN,
|
||||
codec_thread_name IF_PRIO(, PRIORITY_PLAYBACK)
|
||||
IF_COP(, CPU));
|
||||
|
||||
queue_enable_queue_send(&codec_queue, &codec_queue_sender_list,
|
||||
codec_thread_p);
|
||||
codec_thread_id);
|
||||
|
||||
audio_thread_p = create_thread(audio_thread, audio_stack,
|
||||
audio_thread_id = create_thread(audio_thread, audio_stack,
|
||||
sizeof(audio_stack), CREATE_THREAD_FROZEN,
|
||||
audio_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
|
||||
IF_COP(, CPU));
|
||||
|
||||
queue_enable_queue_send(&audio_queue, &audio_queue_sender_list,
|
||||
audio_thread_p);
|
||||
audio_thread_id);
|
||||
|
||||
#ifdef PLAYBACK_VOICE
|
||||
voice_thread_init();
|
||||
|
@ -2599,8 +2599,8 @@ void audio_init(void)
|
|||
#ifdef PLAYBACK_VOICE
|
||||
voice_thread_resume();
|
||||
#endif
|
||||
thread_thaw(codec_thread_p);
|
||||
thread_thaw(audio_thread_p);
|
||||
thread_thaw(codec_thread_id);
|
||||
thread_thaw(audio_thread_id);
|
||||
|
||||
} /* audio_init */
|
||||
|
||||
|
|
|
@ -146,7 +146,8 @@ static const struct plugin_api rockbox_api = {
|
|||
font_get_width,
|
||||
screen_clear_area,
|
||||
gui_scrollbar_draw,
|
||||
#endif
|
||||
#endif /* HAVE_LCD_BITMAP */
|
||||
get_codepage_name,
|
||||
|
||||
backlight_on,
|
||||
backlight_off,
|
||||
|
@ -482,6 +483,7 @@ static const struct plugin_api rockbox_api = {
|
|||
&statusbars,
|
||||
gui_syncstatusbar_draw,
|
||||
/* options */
|
||||
get_settings_list,
|
||||
find_setting,
|
||||
option_screen,
|
||||
set_option,
|
||||
|
@ -619,8 +621,6 @@ static const struct plugin_api rockbox_api = {
|
|||
appsversion,
|
||||
/* new stuff at the end, sort into place next time
|
||||
the API gets incompatible */
|
||||
get_settings_list,
|
||||
get_codepage_name,
|
||||
};
|
||||
|
||||
int plugin_load(const char* plugin, const void* parameter)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 Björn Stenberg
|
||||
* Copyright (C) 2002 Björn Stenberg
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -131,12 +131,12 @@ void* plugin_get_buffer(size_t *buffer_size);
|
|||
#define PLUGIN_MAGIC 0x526F634B /* RocK */
|
||||
|
||||
/* increase this every time the api struct changes */
|
||||
#define PLUGIN_API_VERSION 128
|
||||
#define PLUGIN_API_VERSION 129
|
||||
|
||||
/* update this to latest version if a change to the api struct breaks
|
||||
backwards compatibility (and please take the opportunity to sort in any
|
||||
new function which are "waiting" at the end of the function table) */
|
||||
#define PLUGIN_MIN_API_VERSION 127
|
||||
#define PLUGIN_MIN_API_VERSION 129
|
||||
|
||||
/* plugin return codes */
|
||||
enum plugin_status {
|
||||
|
@ -244,6 +244,7 @@ struct plugin_api {
|
|||
int min_shown, int max_shown,
|
||||
unsigned flags);
|
||||
#endif /* HAVE_LCD_BITMAP */
|
||||
const char* (*get_codepage_name)(int cp);
|
||||
|
||||
/* backlight */
|
||||
/* The backlight_* functions must be present in the API regardless whether
|
||||
|
@ -408,13 +409,13 @@ struct plugin_api {
|
|||
long (*default_event_handler)(long event);
|
||||
long (*default_event_handler_ex)(long event, void (*callback)(void *), void *parameter);
|
||||
struct thread_entry* threads;
|
||||
struct thread_entry* (*create_thread)(void (*function)(void), void* stack,
|
||||
size_t stack_size, unsigned flags,
|
||||
const char *name
|
||||
IF_PRIO(, int priority)
|
||||
IF_COP(, unsigned int core));
|
||||
unsigned int (*create_thread)(void (*function)(void), void* stack,
|
||||
size_t stack_size, unsigned flags,
|
||||
const char *name
|
||||
IF_PRIO(, int priority)
|
||||
IF_COP(, unsigned int core));
|
||||
void (*thread_exit)(void);
|
||||
void (*thread_wait)(struct thread_entry *thread);
|
||||
void (*thread_wait)(unsigned int thread_id);
|
||||
#if CONFIG_CODEC == SWCODEC
|
||||
void (*mutex_init)(struct mutex *m);
|
||||
void (*mutex_lock)(struct mutex *m);
|
||||
|
@ -456,7 +457,7 @@ struct plugin_api {
|
|||
#if CONFIG_CODEC == SWCODEC
|
||||
void (*queue_enable_queue_send)(struct event_queue *q,
|
||||
struct queue_sender_list *send,
|
||||
struct thread_entry *owner);
|
||||
unsigned int thread_id);
|
||||
bool (*queue_empty)(const struct event_queue *q);
|
||||
void (*queue_wait)(struct event_queue *q, struct queue_event *ev);
|
||||
intptr_t (*queue_send)(struct event_queue *q, long id,
|
||||
|
@ -616,6 +617,7 @@ struct plugin_api {
|
|||
void (*gui_syncstatusbar_draw)(struct gui_syncstatusbar * bars, bool force_redraw);
|
||||
|
||||
/* options */
|
||||
const struct settings_list* (*get_settings_list)(int*count);
|
||||
const struct settings_list* (*find_setting)(const void* variable, int *id);
|
||||
bool (*option_screen)(const struct settings_list *setting,
|
||||
struct viewport parent[NB_SCREENS],
|
||||
|
@ -771,7 +773,7 @@ struct plugin_api {
|
|||
char *buf, int buflen);
|
||||
#endif
|
||||
|
||||
void (*thread_thaw)(struct thread_entry *thread);
|
||||
void (*thread_thaw)(unsigned int thread_id);
|
||||
|
||||
#ifdef HAVE_SEMAPHORE_OBJECTS
|
||||
void (*semaphore_init)(struct semaphore *s, int max, int start);
|
||||
|
@ -782,8 +784,6 @@ struct plugin_api {
|
|||
const char *appsversion;
|
||||
/* new stuff at the end, sort into place next time
|
||||
the API gets incompatible */
|
||||
const struct settings_list* (*get_settings_list)(int*count);
|
||||
const char* (*get_codepage_name)(int cp);
|
||||
};
|
||||
|
||||
/* plugin header */
|
||||
|
|
|
@ -206,7 +206,7 @@ struct
|
|||
{
|
||||
bool foreground; /* set as long as we're owning the UI */
|
||||
bool exiting; /* signal to the thread that we want to exit */
|
||||
struct thread_entry *thread; /* worker thread id */
|
||||
unsigned int thread; /* worker thread id */
|
||||
} gTread;
|
||||
|
||||
static const struct plugin_api* rb; /* here is the global API struct pointer */
|
||||
|
|
|
@ -216,7 +216,7 @@ struct batt_info
|
|||
|
||||
#define BUF_ELEMENTS (sizeof(bat)/sizeof(struct batt_info))
|
||||
|
||||
static struct thread_entry *thread_id;
|
||||
static unsigned int thread_id;
|
||||
static struct event_queue thread_q;
|
||||
static bool in_usb_mode;
|
||||
static unsigned int buf_idx;
|
||||
|
@ -537,7 +537,7 @@ int main(void)
|
|||
if ((thread_id = rb->create_thread(thread, thread_stack,
|
||||
sizeof(thread_stack), 0, "Battery Benchmark"
|
||||
IF_PRIO(, PRIORITY_BACKGROUND)
|
||||
IF_COP(, CPU))) == NULL)
|
||||
IF_COP(, CPU))) == 0)
|
||||
{
|
||||
rb->splash(HZ, "Cannot create thread!");
|
||||
return PLUGIN_ERROR;
|
||||
|
|
|
@ -732,7 +732,7 @@ bool audio_thread_init(void)
|
|||
rb->queue_enable_queue_send(audio_str.hdr.q, &audio_str_queue_send,
|
||||
audio_str.thread);
|
||||
|
||||
if (audio_str.thread == NULL)
|
||||
if (audio_str.thread == 0)
|
||||
return false;
|
||||
|
||||
/* Wait for thread to initialize */
|
||||
|
@ -744,11 +744,11 @@ bool audio_thread_init(void)
|
|||
/* Stops the audio thread */
|
||||
void audio_thread_exit(void)
|
||||
{
|
||||
if (audio_str.thread != NULL)
|
||||
if (audio_str.thread != 0)
|
||||
{
|
||||
str_post_msg(&audio_str, STREAM_QUIT, 0);
|
||||
rb->thread_wait(audio_str.thread);
|
||||
audio_str.thread = NULL;
|
||||
audio_str.thread = 0;
|
||||
}
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
|
|
@ -835,7 +835,7 @@ void disk_buf_reply_msg(intptr_t retval)
|
|||
|
||||
bool disk_buf_init(void)
|
||||
{
|
||||
disk_buf.thread = NULL;
|
||||
disk_buf.thread = 0;
|
||||
list_initialize(&nf_list);
|
||||
|
||||
rb->mutex_init(&disk_buf_mtx);
|
||||
|
@ -893,7 +893,7 @@ bool disk_buf_init(void)
|
|||
rb->queue_enable_queue_send(disk_buf.q, &disk_buf_queue_send,
|
||||
disk_buf.thread);
|
||||
|
||||
if (disk_buf.thread == NULL)
|
||||
if (disk_buf.thread == 0)
|
||||
return false;
|
||||
|
||||
/* Wait for thread to initialize */
|
||||
|
@ -904,10 +904,10 @@ bool disk_buf_init(void)
|
|||
|
||||
void disk_buf_exit(void)
|
||||
{
|
||||
if (disk_buf.thread != NULL)
|
||||
if (disk_buf.thread != 0)
|
||||
{
|
||||
rb->queue_post(disk_buf.q, STREAM_QUIT, 0);
|
||||
rb->thread_wait(disk_buf.thread);
|
||||
disk_buf.thread = NULL;
|
||||
disk_buf.thread = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ struct dbuf_range
|
|||
* playback events as well as buffering */
|
||||
struct disk_buf
|
||||
{
|
||||
struct thread_entry *thread;
|
||||
unsigned int thread;
|
||||
struct event_queue *q;
|
||||
uint8_t *start; /* Start pointer */
|
||||
uint8_t *end; /* End of buffer pointer less MPEG_GUARDBUF_SIZE. The
|
||||
|
|
|
@ -1027,7 +1027,7 @@ intptr_t parser_send_video_msg(long id, intptr_t data)
|
|||
{
|
||||
intptr_t retval = 0;
|
||||
|
||||
if (video_str.thread != NULL && disk_buf.in_file >= 0)
|
||||
if (video_str.thread != 0 && disk_buf.in_file >= 0)
|
||||
{
|
||||
/* Hook certain messages since they involve multiple operations
|
||||
* behind the scenes */
|
||||
|
|
|
@ -908,7 +908,7 @@ static void stream_mgr_thread(void)
|
|||
/* Opens a new file */
|
||||
int stream_open(const char *filename)
|
||||
{
|
||||
if (stream_mgr.thread != NULL)
|
||||
if (stream_mgr.thread != 0)
|
||||
return stream_mgr_send_msg(STREAM_OPEN, (intptr_t)filename);
|
||||
return STREAM_ERROR;
|
||||
}
|
||||
|
@ -916,7 +916,7 @@ int stream_open(const char *filename)
|
|||
/* Plays the current file starting at time 'start' */
|
||||
int stream_play(void)
|
||||
{
|
||||
if (stream_mgr.thread != NULL)
|
||||
if (stream_mgr.thread != 0)
|
||||
return stream_mgr_send_msg(STREAM_PLAY, 0);
|
||||
return STREAM_ERROR;
|
||||
}
|
||||
|
@ -924,7 +924,7 @@ int stream_play(void)
|
|||
/* Pauses playback if playing */
|
||||
int stream_pause(void)
|
||||
{
|
||||
if (stream_mgr.thread != NULL)
|
||||
if (stream_mgr.thread != 0)
|
||||
return stream_mgr_send_msg(STREAM_PAUSE, false);
|
||||
return STREAM_ERROR;
|
||||
}
|
||||
|
@ -932,7 +932,7 @@ int stream_pause(void)
|
|||
/* Resumes playback if paused */
|
||||
int stream_resume(void)
|
||||
{
|
||||
if (stream_mgr.thread != NULL)
|
||||
if (stream_mgr.thread != 0)
|
||||
return stream_mgr_send_msg(STREAM_PAUSE, true);
|
||||
return STREAM_ERROR;
|
||||
}
|
||||
|
@ -940,7 +940,7 @@ int stream_resume(void)
|
|||
/* Stops playback if not stopped */
|
||||
int stream_stop(void)
|
||||
{
|
||||
if (stream_mgr.thread != NULL)
|
||||
if (stream_mgr.thread != 0)
|
||||
return stream_mgr_send_msg(STREAM_STOP, 0);
|
||||
return STREAM_ERROR;
|
||||
}
|
||||
|
@ -950,7 +950,7 @@ int stream_seek(uint32_t time, int whence)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (stream_mgr.thread == NULL)
|
||||
if (stream_mgr.thread == 0)
|
||||
return STREAM_ERROR;
|
||||
|
||||
stream_mgr_lock();
|
||||
|
@ -968,7 +968,7 @@ int stream_seek(uint32_t time, int whence)
|
|||
/* Closes the current file */
|
||||
int stream_close(void)
|
||||
{
|
||||
if (stream_mgr.thread != NULL)
|
||||
if (stream_mgr.thread != 0)
|
||||
return stream_mgr_send_msg(STREAM_CLOSE, 0);
|
||||
return STREAM_ERROR;
|
||||
}
|
||||
|
@ -1018,7 +1018,7 @@ int stream_init(void)
|
|||
rb->queue_enable_queue_send(stream_mgr.q, &stream_mgr_queue_send,
|
||||
stream_mgr.thread);
|
||||
|
||||
if (stream_mgr.thread == NULL)
|
||||
if (stream_mgr.thread == 0)
|
||||
{
|
||||
rb->splash(HZ, "Could not create stream manager thread!");
|
||||
return STREAM_ERROR;
|
||||
|
@ -1073,11 +1073,11 @@ void stream_exit(void)
|
|||
disk_buf_exit();
|
||||
pcm_output_exit();
|
||||
|
||||
if (stream_mgr.thread != NULL)
|
||||
if (stream_mgr.thread != 0)
|
||||
{
|
||||
stream_mgr_post_msg(STREAM_QUIT, 0);
|
||||
rb->thread_wait(stream_mgr.thread);
|
||||
stream_mgr.thread = NULL;
|
||||
stream_mgr.thread = 0;
|
||||
}
|
||||
|
||||
#ifndef HAVE_LCD_COLOR
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
* coordination with assistance from the parser */
|
||||
struct stream_mgr
|
||||
{
|
||||
struct thread_entry *thread; /* Playback control thread */
|
||||
unsigned int thread; /* Playback control thread */
|
||||
struct event_queue *q; /* event queue for control thread */
|
||||
const char *filename; /* Current filename */
|
||||
uint32_t resume_time; /* The stream tick where playback was
|
||||
|
|
|
@ -45,7 +45,7 @@ struct stream_hdr
|
|||
struct stream
|
||||
{
|
||||
struct stream_hdr hdr; /* Base stream data */
|
||||
struct thread_entry *thread; /* Stream's thread */
|
||||
unsigned int thread; /* Stream's thread */
|
||||
uint8_t* curr_packet; /* Current stream packet beginning */
|
||||
uint8_t* curr_packet_end; /* Current stream packet end */
|
||||
struct list_item l; /* List of streams - either reserve pool
|
||||
|
|
|
@ -1009,7 +1009,7 @@ bool video_thread_init(void)
|
|||
rb->queue_enable_queue_send(video_str.hdr.q, &video_str_queue_send,
|
||||
video_str.thread);
|
||||
|
||||
if (video_str.thread == NULL)
|
||||
if (video_str.thread == 0)
|
||||
return false;
|
||||
|
||||
/* Wait for thread to initialize */
|
||||
|
@ -1022,11 +1022,11 @@ bool video_thread_init(void)
|
|||
/* Terminates the video thread */
|
||||
void video_thread_exit(void)
|
||||
{
|
||||
if (video_str.thread != NULL)
|
||||
if (video_str.thread != 0)
|
||||
{
|
||||
str_post_msg(&video_str, STREAM_QUIT, 0);
|
||||
rb->thread_wait(video_str.thread);
|
||||
IF_COP(invalidate_icache());
|
||||
video_str.thread = NULL;
|
||||
video_str.thread = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -218,7 +218,7 @@ struct mutex slide_cache_stack_lock;
|
|||
|
||||
static int empty_slide_hid;
|
||||
|
||||
struct thread_entry *thread_id;
|
||||
unsigned int thread_id;
|
||||
struct event_queue thread_q;
|
||||
|
||||
static char tmp_path_name[MAX_PATH];
|
||||
|
@ -831,7 +831,7 @@ bool create_pf_thread(void)
|
|||
IF_PRIO(, PRIORITY_BACKGROUND)
|
||||
IF_COP(, CPU)
|
||||
)
|
||||
) == NULL) {
|
||||
) == 0) {
|
||||
return false;
|
||||
}
|
||||
thread_is_running = true;
|
||||
|
|
|
@ -525,7 +525,7 @@ static enum plugin_status test_track(const char* filename)
|
|||
long ticks;
|
||||
unsigned long speed;
|
||||
unsigned long duration;
|
||||
struct thread_entry* codecthread_id;
|
||||
unsigned int codecthread_id;
|
||||
const char* ch;
|
||||
|
||||
/* Display filename (excluding any path)*/
|
||||
|
@ -590,7 +590,7 @@ static enum plugin_status test_track(const char* filename)
|
|||
|
||||
if ((codecthread_id = rb->create_thread(codec_thread,
|
||||
codec_stack, codec_stack_size, 0, "testcodec"
|
||||
IF_PRIO(,PRIORITY_PLAYBACK) IF_COP(, CPU))) == NULL)
|
||||
IF_PRIO(,PRIORITY_PLAYBACK) IF_COP(, CPU))) == 0)
|
||||
{
|
||||
log_text("Cannot create codec thread!",true);
|
||||
goto exit;
|
||||
|
|
|
@ -39,7 +39,7 @@ static unsigned long hw_sampr IDATA_ATTR = HW_SAMPR_DEFAULT;
|
|||
|
||||
static int gen_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)] IBSS_ATTR;
|
||||
static bool gen_quit IBSS_ATTR;
|
||||
static struct thread_entry *gen_thread_p;
|
||||
static unsigned int gen_thread_id;
|
||||
|
||||
#define OUTPUT_CHUNK_COUNT (1 << 1)
|
||||
#define OUTPUT_CHUNK_MASK (OUTPUT_CHUNK_COUNT-1)
|
||||
|
@ -233,11 +233,11 @@ static void play_tone(bool volume_set)
|
|||
output_clear();
|
||||
update_gen_step();
|
||||
|
||||
gen_thread_p = rb->create_thread(gen_thread_func, gen_thread_stack,
|
||||
sizeof(gen_thread_stack), 0,
|
||||
"test_sampr generator"
|
||||
IF_PRIO(, PRIORITY_PLAYBACK)
|
||||
IF_COP(, CPU));
|
||||
gen_thread_id = rb->create_thread(gen_thread_func, gen_thread_stack,
|
||||
sizeof(gen_thread_stack), 0,
|
||||
"test_sampr generator"
|
||||
IF_PRIO(, PRIORITY_PLAYBACK)
|
||||
IF_COP(, CPU));
|
||||
|
||||
rb->pcm_play_data(get_more, NULL, 0);
|
||||
|
||||
|
@ -260,7 +260,7 @@ static void play_tone(bool volume_set)
|
|||
|
||||
gen_quit = true;
|
||||
|
||||
rb->thread_wait(gen_thread_p);
|
||||
rb->thread_wait(gen_thread_id);
|
||||
|
||||
rb->pcm_play_stop();
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
/***************************************************************************/
|
||||
|
||||
extern struct thread_entry *codec_thread_p;
|
||||
extern uintptr_t codec_thread_id;
|
||||
|
||||
/** General recording state **/
|
||||
static bool is_recording; /* We are recording */
|
||||
|
@ -220,7 +220,7 @@ static struct event_queue pcmrec_queue SHAREDBSS_ATTR;
|
|||
static struct queue_sender_list pcmrec_queue_send SHAREDBSS_ATTR;
|
||||
static long pcmrec_stack[3*DEFAULT_STACK_SIZE/sizeof(long)];
|
||||
static const char pcmrec_thread_name[] = "pcmrec";
|
||||
static struct thread_entry *pcmrec_thread_p;
|
||||
static unsigned int pcmrec_thread_id = 0;
|
||||
|
||||
static void pcmrec_thread(void);
|
||||
|
||||
|
@ -365,12 +365,12 @@ unsigned long pcm_rec_sample_rate(void)
|
|||
void pcm_rec_init(void)
|
||||
{
|
||||
queue_init(&pcmrec_queue, true);
|
||||
pcmrec_thread_p =
|
||||
pcmrec_thread_id =
|
||||
create_thread(pcmrec_thread, pcmrec_stack, sizeof(pcmrec_stack),
|
||||
0, pcmrec_thread_name IF_PRIO(, PRIORITY_RECORDING)
|
||||
IF_COP(, CPU));
|
||||
queue_enable_queue_send(&pcmrec_queue, &pcmrec_queue_send,
|
||||
pcmrec_thread_p);
|
||||
pcmrec_thread_id);
|
||||
} /* pcm_rec_init */
|
||||
|
||||
/** audio_* group **/
|
||||
|
@ -878,10 +878,10 @@ static void pcmrec_flush(unsigned flush_num)
|
|||
priority until finished */
|
||||
logf("pcmrec: boost (%s)",
|
||||
num >= flood_watermark ? "num" : "time");
|
||||
prio_pcmrec = thread_set_priority(NULL,
|
||||
thread_get_priority(NULL) - 4);
|
||||
prio_codec = thread_set_priority(codec_thread_p,
|
||||
thread_get_priority(codec_thread_p) - 4);
|
||||
prio_pcmrec = thread_set_priority(THREAD_ID_CURRENT,
|
||||
thread_get_priority(THREAD_ID_CURRENT) - 4);
|
||||
prio_codec = thread_set_priority(codec_thread_id,
|
||||
thread_get_priority(codec_thread_id) - 4);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -931,8 +931,8 @@ static void pcmrec_flush(unsigned flush_num)
|
|||
{
|
||||
/* return to original priorities */
|
||||
logf("pcmrec: unboost priority");
|
||||
thread_set_priority(NULL, prio_pcmrec);
|
||||
thread_set_priority(codec_thread_p, prio_codec);
|
||||
thread_set_priority(THREAD_ID_CURRENT, prio_pcmrec);
|
||||
thread_set_priority(codec_thread_id, prio_codec);
|
||||
}
|
||||
|
||||
last_flush_tick = current_tick; /* save tick when we left */
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
#define VOICE_SAMPLE_DEPTH 16 /* Sample depth in bits */
|
||||
|
||||
/* Voice thread variables */
|
||||
static struct thread_entry *voice_thread_p = NULL;
|
||||
static unsigned int voice_thread_id = 0;
|
||||
static long voice_stack[0x7c0/sizeof(long)] IBSS_ATTR_VOICE_STACK;
|
||||
static const char voice_thread_name[] = "voice";
|
||||
|
||||
|
@ -434,25 +434,25 @@ void voice_thread_init(void)
|
|||
queue_init(&voice_queue, false);
|
||||
mutex_init(&voice_mutex);
|
||||
|
||||
voice_thread_p = create_thread(voice_thread, voice_stack,
|
||||
voice_thread_id = create_thread(voice_thread, voice_stack,
|
||||
sizeof(voice_stack), CREATE_THREAD_FROZEN,
|
||||
voice_thread_name IF_PRIO(, PRIORITY_PLAYBACK) IF_COP(, CPU));
|
||||
|
||||
queue_enable_queue_send(&voice_queue, &voice_queue_sender_list,
|
||||
voice_thread_p);
|
||||
voice_thread_id);
|
||||
} /* voice_thread_init */
|
||||
|
||||
/* Unfreeze the voice thread */
|
||||
void voice_thread_resume(void)
|
||||
{
|
||||
logf("Thawing voice thread");
|
||||
thread_thaw(voice_thread_p);
|
||||
thread_thaw(voice_thread_id);
|
||||
}
|
||||
|
||||
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||
/* Set the voice thread priority */
|
||||
void voice_thread_set_priority(int priority)
|
||||
{
|
||||
thread_set_priority(voice_thread_p, priority);
|
||||
thread_set_priority(voice_thread_id, priority);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -130,7 +130,7 @@ static long backlight_stack[DEFAULT_STACK_SIZE/sizeof(long)];
|
|||
static const char backlight_thread_name[] = "backlight";
|
||||
static struct event_queue backlight_queue;
|
||||
#ifdef BACKLIGHT_DRIVER_CLOSE
|
||||
static struct thread_entry *backlight_thread_p = NULL;
|
||||
static unsigned int backlight_thread_id = 0;
|
||||
#endif
|
||||
|
||||
static int backlight_timer SHAREDBSS_ATTR;
|
||||
|
@ -744,7 +744,7 @@ void backlight_init(void)
|
|||
* call the appropriate backlight_set_*() functions, only changing light
|
||||
* status if necessary. */
|
||||
#ifdef BACKLIGHT_DRIVER_CLOSE
|
||||
backlight_thread_p =
|
||||
backlight_thread_id =
|
||||
#endif
|
||||
create_thread(backlight_thread, backlight_stack,
|
||||
sizeof(backlight_stack), 0, backlight_thread_name
|
||||
|
@ -756,13 +756,13 @@ void backlight_init(void)
|
|||
#ifdef BACKLIGHT_DRIVER_CLOSE
|
||||
void backlight_close(void)
|
||||
{
|
||||
struct thread_entry *thread = backlight_thread_p;
|
||||
unsigned int thread = backlight_thread_id;
|
||||
|
||||
/* Wait for thread to exit */
|
||||
if (thread == NULL)
|
||||
if (thread == 0)
|
||||
return;
|
||||
|
||||
backlight_thread_p = NULL;
|
||||
backlight_thread_id = 0;
|
||||
|
||||
queue_post(&backlight_queue, BACKLIGHT_QUIT, 0);
|
||||
thread_wait(thread);
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
#endif
|
||||
|
||||
#ifdef ATA_DRIVER_CLOSE
|
||||
static struct thread_entry *ata_thread_p = NULL;
|
||||
static unsigned int ata_thread_id = 0;
|
||||
#endif
|
||||
|
||||
#if defined(MAX_PHYS_SECTOR_SIZE) && MEM == 64
|
||||
|
@ -94,7 +94,8 @@ static void ata_lock_init(struct ata_lock *l)
|
|||
|
||||
static void ata_lock_lock(struct ata_lock *l)
|
||||
{
|
||||
struct thread_entry * const current = thread_get_current();
|
||||
struct thread_entry * const current =
|
||||
thread_id_entry(THREAD_ID_CURRENT);
|
||||
|
||||
if (current == l->thread)
|
||||
{
|
||||
|
@ -1350,7 +1351,7 @@ int ata_init(void)
|
|||
|
||||
last_disk_activity = current_tick;
|
||||
#ifdef ATA_DRIVER_CLOSE
|
||||
ata_thread_p =
|
||||
ata_thread_id =
|
||||
#endif
|
||||
create_thread(ata_thread, ata_stack,
|
||||
sizeof(ata_stack), 0, ata_thread_name
|
||||
|
@ -1370,15 +1371,15 @@ int ata_init(void)
|
|||
#ifdef ATA_DRIVER_CLOSE
|
||||
void ata_close(void)
|
||||
{
|
||||
struct thread_entry *thread = ata_thread_p;
|
||||
unsigned int thread_id = ata_thread_id;
|
||||
|
||||
if (thread == NULL)
|
||||
if (thread_id == 0)
|
||||
return;
|
||||
|
||||
ata_thread_p = NULL;
|
||||
ata_thread_id = 0;
|
||||
|
||||
queue_post(&ata_queue, Q_CLOSE, 0);
|
||||
thread_wait(thread);
|
||||
thread_wait(thread_id);
|
||||
}
|
||||
#endif /* ATA_DRIVER_CLOSE */
|
||||
|
||||
|
|
|
@ -261,7 +261,7 @@ extern void queue_post(struct event_queue *q, long id, intptr_t data);
|
|||
#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
|
||||
extern void queue_enable_queue_send(struct event_queue *q,
|
||||
struct queue_sender_list *send,
|
||||
struct thread_entry *owner);
|
||||
unsigned int owner_id);
|
||||
extern intptr_t queue_send(struct event_queue *q, long id, intptr_t data);
|
||||
extern void queue_reply(struct event_queue *q, intptr_t retval);
|
||||
extern bool queue_in_queue_send(struct event_queue *q);
|
||||
|
|
|
@ -58,9 +58,6 @@
|
|||
#define NUM_PRIORITIES 32
|
||||
#define PRIORITY_IDLE 32 /* Priority representative of no tasks */
|
||||
|
||||
/* TODO: Only a minor tweak to create_thread would be needed to let
|
||||
* thread slots be caller allocated - no essential threading functionality
|
||||
* depends upon an array */
|
||||
#if CONFIG_CODEC == SWCODEC
|
||||
|
||||
#ifdef HAVE_RECORDING
|
||||
|
@ -280,6 +277,7 @@ struct thread_entry
|
|||
int skip_count; /* Number of times skipped if higher priority
|
||||
thread was running */
|
||||
#endif
|
||||
uint16_t id; /* Current slot id */
|
||||
unsigned short stack_size; /* Size of stack in bytes */
|
||||
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||
unsigned char base_priority; /* Base priority (set explicitly during
|
||||
|
@ -298,6 +296,16 @@ struct thread_entry
|
|||
#endif
|
||||
};
|
||||
|
||||
/*** Macros for internal use ***/
|
||||
/* Thread ID, 16 bits = |VVVVVVVV|SSSSSSSS| */
|
||||
#define THREAD_ID_VERSION_SHIFT 8
|
||||
#define THREAD_ID_VERSION_MASK 0xff00
|
||||
#define THREAD_ID_SLOT_MASK 0x00ff
|
||||
#define THREAD_ID_INIT(n) ((1u << THREAD_ID_VERSION_SHIFT) | (n))
|
||||
|
||||
/* Specify current thread in a function taking an ID. */
|
||||
#define THREAD_ID_CURRENT ((unsigned int)-1)
|
||||
|
||||
#if NUM_CORES > 1
|
||||
/* Operations to be performed just before stopping a thread and starting
|
||||
a new one if specified before calling switch_thread */
|
||||
|
@ -475,11 +483,11 @@ void init_threads(void);
|
|||
|
||||
/* Allocate a thread in the scheduler */
|
||||
#define CREATE_THREAD_FROZEN 0x00000001 /* Thread is frozen at create time */
|
||||
struct thread_entry*
|
||||
create_thread(void (*function)(void), void* stack, size_t stack_size,
|
||||
unsigned flags, const char *name
|
||||
IF_PRIO(, int priority)
|
||||
IF_COP(, unsigned int core));
|
||||
unsigned int create_thread(void (*function)(void),
|
||||
void* stack, size_t stack_size,
|
||||
unsigned flags, const char *name
|
||||
IF_PRIO(, int priority)
|
||||
IF_COP(, unsigned int core));
|
||||
|
||||
/* Set and clear the CPU frequency boost flag for the calling thread */
|
||||
#ifdef HAVE_SCHEDULER_BOOSTCTRL
|
||||
|
@ -489,17 +497,19 @@ void cancel_cpu_boost(void);
|
|||
#define trigger_cpu_boost()
|
||||
#define cancel_cpu_boost()
|
||||
#endif
|
||||
/* Return thread entry from id */
|
||||
struct thread_entry *thread_id_entry(unsigned int thread_id);
|
||||
/* Make a frozed thread runnable (when started with CREATE_THREAD_FROZEN).
|
||||
* Has no effect on a thread not frozen. */
|
||||
void thread_thaw(struct thread_entry *thread);
|
||||
void thread_thaw(unsigned int thread_id);
|
||||
/* Wait for a thread to exit */
|
||||
void thread_wait(struct thread_entry *thread);
|
||||
void thread_wait(unsigned int thread_id);
|
||||
/* Exit the current thread */
|
||||
void thread_exit(void);
|
||||
#if defined(DEBUG) || defined(ROCKBOX_HAS_LOGF)
|
||||
#define ALLOW_REMOVE_THREAD
|
||||
/* Remove a thread from the scheduler */
|
||||
void remove_thread(struct thread_entry *thread);
|
||||
void remove_thread(unsigned int thread_id);
|
||||
#endif
|
||||
|
||||
/* Switch to next runnable thread */
|
||||
|
@ -526,13 +536,13 @@ unsigned int thread_queue_wake(struct thread_entry **list);
|
|||
unsigned int wakeup_thread(struct thread_entry **list);
|
||||
|
||||
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||
int thread_set_priority(struct thread_entry *thread, int priority);
|
||||
int thread_get_priority(struct thread_entry *thread);
|
||||
int thread_set_priority(unsigned int thread_id, int priority);
|
||||
int thread_get_priority(unsigned int thread_id);
|
||||
#endif /* HAVE_PRIORITY_SCHEDULING */
|
||||
#if NUM_CORES > 1
|
||||
unsigned int switch_core(unsigned int new_core);
|
||||
#endif
|
||||
struct thread_entry * thread_get_current(void);
|
||||
unsigned int thread_get_current(void);
|
||||
|
||||
/* Debugging info - only! */
|
||||
int thread_stack_usage(const struct thread_entry *thread);
|
||||
|
|
|
@ -352,11 +352,12 @@ static void queue_remove_sender_thread_cb(struct thread_entry *thread)
|
|||
* specified for priority inheritance to operate.
|
||||
*
|
||||
* Use of queue_wait(_w_tmo) by multiple threads on a queue using synchronous
|
||||
* messages results in an undefined order of message replies.
|
||||
* messages results in an undefined order of message replies or possible default
|
||||
* replies if two or more waits happen before a reply is done.
|
||||
*/
|
||||
void queue_enable_queue_send(struct event_queue *q,
|
||||
struct queue_sender_list *send,
|
||||
struct thread_entry *owner)
|
||||
unsigned int owner_id)
|
||||
{
|
||||
int oldlevel = disable_irq_save();
|
||||
corelock_lock(&q->cl);
|
||||
|
@ -367,9 +368,11 @@ void queue_enable_queue_send(struct event_queue *q,
|
|||
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||
send->blocker.wakeup_protocol = wakeup_priority_protocol_release;
|
||||
send->blocker.priority = PRIORITY_IDLE;
|
||||
send->blocker.thread = owner;
|
||||
if(owner != NULL)
|
||||
if(owner_id != 0)
|
||||
{
|
||||
send->blocker.thread = thread_id_entry(owner_id);
|
||||
q->blocker_p = &send->blocker;
|
||||
}
|
||||
#endif
|
||||
q->send = send;
|
||||
}
|
||||
|
@ -377,7 +380,7 @@ void queue_enable_queue_send(struct event_queue *q,
|
|||
corelock_unlock(&q->cl);
|
||||
restore_irq(oldlevel);
|
||||
|
||||
(void)owner;
|
||||
(void)owner_id;
|
||||
}
|
||||
|
||||
/* Unblock a blocked thread at a given event index */
|
||||
|
@ -532,7 +535,7 @@ void queue_wait(struct event_queue *q, struct queue_event *ev)
|
|||
|
||||
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||
KERNEL_ASSERT(QUEUE_GET_THREAD(q) == NULL ||
|
||||
QUEUE_GET_THREAD(q) == thread_get_current(),
|
||||
QUEUE_GET_THREAD(q) == cores[CURRENT_CORE].running,
|
||||
"queue_wait->wrong thread\n");
|
||||
#endif
|
||||
|
||||
|
@ -579,7 +582,7 @@ void queue_wait_w_tmo(struct event_queue *q, struct queue_event *ev, int ticks)
|
|||
|
||||
#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
|
||||
KERNEL_ASSERT(QUEUE_GET_THREAD(q) == NULL ||
|
||||
QUEUE_GET_THREAD(q) == thread_get_current(),
|
||||
QUEUE_GET_THREAD(q) == cores[CURRENT_CORE].running,
|
||||
"queue_wait_w_tmo->wrong thread\n");
|
||||
#endif
|
||||
|
||||
|
@ -914,10 +917,10 @@ void mutex_lock(struct mutex *m)
|
|||
void mutex_unlock(struct mutex *m)
|
||||
{
|
||||
/* unlocker not being the owner is an unlocking violation */
|
||||
KERNEL_ASSERT(MUTEX_GET_THREAD(m) == thread_get_current(),
|
||||
KERNEL_ASSERT(MUTEX_GET_THREAD(m) == cores[CURRENT_CORE].running,
|
||||
"mutex_unlock->wrong thread (%s != %s)\n",
|
||||
MUTEX_GET_THREAD(m)->name,
|
||||
thread_get_current()->name);
|
||||
cores[CURRENT_CORE].running->name);
|
||||
|
||||
if(m->count > 0)
|
||||
{
|
||||
|
@ -990,7 +993,7 @@ void spinlock_lock(struct spinlock *l)
|
|||
void spinlock_unlock(struct spinlock *l)
|
||||
{
|
||||
/* unlocker not being the owner is an unlocking violation */
|
||||
KERNEL_ASSERT(l->thread == thread_get_current(),
|
||||
KERNEL_ASSERT(l->thread == cores[CURRENT_CORE].running,
|
||||
"spinlock_unlock->wrong thread\n");
|
||||
|
||||
if(l->count > 0)
|
||||
|
|
|
@ -69,7 +69,7 @@ static const unsigned char pmic_ints_regs[2] =
|
|||
|
||||
#ifdef PMIC_DRIVER_CLOSE
|
||||
static bool pmic_close = false;
|
||||
static struct thread_entry *mc13783_thread_p = NULL;
|
||||
static unsigned int mc13783_thread_id = 0;
|
||||
#endif
|
||||
|
||||
static void mc13783_interrupt_thread(void)
|
||||
|
@ -149,7 +149,7 @@ void mc13783_init(void)
|
|||
MC13783_GPIO_ISR = (1ul << MC13783_GPIO_LINE);
|
||||
|
||||
#ifdef PMIC_DRIVER_CLOSE
|
||||
mc13783_thread_p =
|
||||
mc13783_thread_id =
|
||||
#endif
|
||||
create_thread(mc13783_interrupt_thread,
|
||||
mc13783_thread_stack, sizeof(mc13783_thread_stack), 0,
|
||||
|
@ -159,16 +159,16 @@ void mc13783_init(void)
|
|||
#ifdef PMIC_DRIVER_CLOSE
|
||||
void mc13783_close(void)
|
||||
{
|
||||
struct thread_entry *thread = mc13783_thread_p;
|
||||
unsigned int thread_id = mc13783_thread_p;
|
||||
|
||||
if (thread == NULL)
|
||||
if (thread_id == 0)
|
||||
return;
|
||||
|
||||
mc13783_thread_p = NULL;
|
||||
mc13783_thread_id = 0;
|
||||
|
||||
pmic_close = true;
|
||||
wakeup_signal(&mc13783_wake);
|
||||
thread_wait(thread);
|
||||
thread_wait(thread_id);
|
||||
}
|
||||
#endif /* PMIC_DRIVER_CLOSE */
|
||||
|
||||
|
|
|
@ -1691,8 +1691,8 @@ struct thread_entry *
|
|||
struct thread_entry *next;
|
||||
int bl_pr;
|
||||
|
||||
THREAD_ASSERT(thread_get_current() == bl_t,
|
||||
"UPPT->wrong thread", thread_get_current());
|
||||
THREAD_ASSERT(cores[CURRENT_CORE].running == bl_t,
|
||||
"UPPT->wrong thread", cores[CURRENT_CORE].running);
|
||||
|
||||
LOCK_THREAD(bl_t);
|
||||
|
||||
|
@ -2031,7 +2031,7 @@ void switch_thread(void)
|
|||
}
|
||||
|
||||
#ifdef RB_PROFILE
|
||||
profile_thread_stopped(thread - threads);
|
||||
profile_thread_stopped(thread->id & THREAD_ID_SLOT_MASK);
|
||||
#endif
|
||||
|
||||
/* Begin task switching by saving our current context so that we can
|
||||
|
@ -2136,7 +2136,7 @@ void switch_thread(void)
|
|||
load_context(&thread->context);
|
||||
|
||||
#ifdef RB_PROFILE
|
||||
profile_thread_started(thread - threads);
|
||||
profile_thread_started(thread->id & THREAD_ID_SLOT_MASK);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -2315,6 +2315,24 @@ unsigned int thread_queue_wake(struct thread_entry **list)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Assign the thread slot a new ID. Version is 1-255.
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
static void new_thread_id(unsigned int slot_num,
|
||||
struct thread_entry *thread)
|
||||
{
|
||||
unsigned int version =
|
||||
(thread->id + (1u << THREAD_ID_VERSION_SHIFT))
|
||||
& THREAD_ID_VERSION_MASK;
|
||||
|
||||
/* If wrapped to 0, make it 1 */
|
||||
if (version == 0)
|
||||
version = 1u << THREAD_ID_VERSION_SHIFT;
|
||||
|
||||
thread->id = version | (slot_num & THREAD_ID_SLOT_MASK);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Find an empty thread slot or MAXTHREADS if none found. The slot returned
|
||||
* will be locked on multicore.
|
||||
|
@ -2349,6 +2367,17 @@ static struct thread_entry * find_empty_thread_slot(void)
|
|||
return thread;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Return the thread_entry pointer for a thread_id. Return the current
|
||||
* thread if the ID is 0 (alias for current).
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
struct thread_entry * thread_id_entry(unsigned int thread_id)
|
||||
{
|
||||
return (thread_id == THREAD_ID_CURRENT) ?
|
||||
cores[CURRENT_CORE].running :
|
||||
&threads[thread_id & THREAD_ID_SLOT_MASK];
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Place the current core in idle mode - woken up on interrupt or wake
|
||||
|
@ -2369,11 +2398,11 @@ void core_idle(void)
|
|||
* Return ID if context area could be allocated, else NULL.
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
struct thread_entry*
|
||||
create_thread(void (*function)(void), void* stack, size_t stack_size,
|
||||
unsigned flags, const char *name
|
||||
IF_PRIO(, int priority)
|
||||
IF_COP(, unsigned int core))
|
||||
unsigned int create_thread(void (*function)(void),
|
||||
void* stack, size_t stack_size,
|
||||
unsigned flags, const char *name
|
||||
IF_PRIO(, int priority)
|
||||
IF_COP(, unsigned int core))
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int stack_words;
|
||||
|
@ -2385,7 +2414,7 @@ struct thread_entry*
|
|||
thread = find_empty_thread_slot();
|
||||
if (thread == NULL)
|
||||
{
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
oldlevel = disable_irq_save();
|
||||
|
@ -2443,15 +2472,15 @@ struct thread_entry*
|
|||
THREAD_STARTUP_INIT(core, thread, function);
|
||||
|
||||
thread->state = state;
|
||||
i = thread->id; /* Snapshot while locked */
|
||||
|
||||
if (state == STATE_RUNNING)
|
||||
core_schedule_wakeup(thread);
|
||||
|
||||
UNLOCK_THREAD(thread);
|
||||
|
||||
restore_irq(oldlevel);
|
||||
|
||||
return thread;
|
||||
return i;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SCHEDULER_BOOSTCTRL
|
||||
|
@ -2489,18 +2518,17 @@ void cancel_cpu_boost(void)
|
|||
* Parameter is the ID as returned from create_thread().
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
void thread_wait(struct thread_entry *thread)
|
||||
void thread_wait(unsigned int thread_id)
|
||||
{
|
||||
struct thread_entry *current = cores[CURRENT_CORE].running;
|
||||
|
||||
if (thread == NULL)
|
||||
thread = current;
|
||||
struct thread_entry *thread = thread_id_entry(thread_id);
|
||||
|
||||
/* Lock thread-as-waitable-object lock */
|
||||
corelock_lock(&thread->waiter_cl);
|
||||
|
||||
/* Be sure it hasn't been killed yet */
|
||||
if (thread->state != STATE_KILLED)
|
||||
if (thread_id == THREAD_ID_CURRENT ||
|
||||
(thread->id == thread_id && thread->state != STATE_KILLED))
|
||||
{
|
||||
IF_COP( current->obj_cl = &thread->waiter_cl; )
|
||||
current->bqp = &thread->queue;
|
||||
|
@ -2538,9 +2566,10 @@ void thread_exit(void)
|
|||
if (current->name == THREAD_DESTRUCT)
|
||||
{
|
||||
/* Thread being killed - become a waiter */
|
||||
unsigned int id = current->id;
|
||||
UNLOCK_THREAD(current);
|
||||
corelock_unlock(¤t->waiter_cl);
|
||||
thread_wait(current);
|
||||
thread_wait(id);
|
||||
THREAD_PANICF("thread_exit->WK:*R", current);
|
||||
}
|
||||
#endif
|
||||
|
@ -2568,7 +2597,13 @@ void thread_exit(void)
|
|||
}
|
||||
|
||||
flush_icache();
|
||||
|
||||
/* At this point, this thread isn't using resources allocated for
|
||||
* execution except the slot itself. */
|
||||
#endif
|
||||
|
||||
/* Update ID for this slot */
|
||||
new_thread_id(current->id, current);
|
||||
current->name = NULL;
|
||||
|
||||
/* Signal this thread */
|
||||
|
@ -2593,7 +2628,7 @@ void thread_exit(void)
|
|||
* leave various objects in an undefined state.
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
void remove_thread(struct thread_entry *thread)
|
||||
void remove_thread(unsigned int thread_id)
|
||||
{
|
||||
#if NUM_CORES > 1
|
||||
/* core is not constant here because of core switching */
|
||||
|
@ -2604,13 +2639,11 @@ void remove_thread(struct thread_entry *thread)
|
|||
const unsigned int core = CURRENT_CORE;
|
||||
#endif
|
||||
struct thread_entry *current = cores[core].running;
|
||||
struct thread_entry *thread = thread_id_entry(thread_id);
|
||||
|
||||
unsigned state;
|
||||
int oldlevel;
|
||||
|
||||
if (thread == NULL)
|
||||
thread = current;
|
||||
|
||||
if (thread == current)
|
||||
thread_exit(); /* Current thread - do normal exit */
|
||||
|
||||
|
@ -2621,10 +2654,8 @@ void remove_thread(struct thread_entry *thread)
|
|||
|
||||
state = thread->state;
|
||||
|
||||
if (state == STATE_KILLED)
|
||||
{
|
||||
if (thread->id != thread_id || state == STATE_KILLED)
|
||||
goto thread_killed;
|
||||
}
|
||||
|
||||
#if NUM_CORES > 1
|
||||
if (thread->name == THREAD_DESTRUCT)
|
||||
|
@ -2633,7 +2664,7 @@ void remove_thread(struct thread_entry *thread)
|
|||
UNLOCK_THREAD(thread);
|
||||
corelock_unlock(&thread->waiter_cl);
|
||||
restore_irq(oldlevel);
|
||||
thread_wait(thread);
|
||||
thread_wait(thread_id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2741,6 +2772,7 @@ IF_COP( retry_state: )
|
|||
/* Otherwise thread is frozen and hasn't run yet */
|
||||
}
|
||||
|
||||
new_thread_id(thread_id, thread);
|
||||
thread->state = STATE_KILLED;
|
||||
|
||||
/* If thread was waiting on itself, it will have been removed above.
|
||||
|
@ -2773,17 +2805,15 @@ thread_killed: /* Thread was already killed */
|
|||
* needed inheritance changes also may happen.
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
int thread_set_priority(struct thread_entry *thread, int priority)
|
||||
int thread_set_priority(unsigned int thread_id, int priority)
|
||||
{
|
||||
int old_base_priority = -1;
|
||||
struct thread_entry *thread = thread_id_entry(thread_id);
|
||||
|
||||
/* A little safety measure */
|
||||
if (priority < HIGHEST_PRIORITY || priority > LOWEST_PRIORITY)
|
||||
return -1;
|
||||
|
||||
if (thread == NULL)
|
||||
thread = cores[CURRENT_CORE].running;
|
||||
|
||||
/* Thread could be on any list and therefore on an interrupt accessible
|
||||
one - disable interrupts */
|
||||
int oldlevel = disable_irq_save();
|
||||
|
@ -2791,7 +2821,8 @@ int thread_set_priority(struct thread_entry *thread, int priority)
|
|||
LOCK_THREAD(thread);
|
||||
|
||||
/* Make sure it's not killed */
|
||||
if (thread->state != STATE_KILLED)
|
||||
if (thread_id == THREAD_ID_CURRENT ||
|
||||
(thread->id == thread_id && thread->state != STATE_KILLED))
|
||||
{
|
||||
int old_priority = thread->priority;
|
||||
|
||||
|
@ -2908,13 +2939,19 @@ int thread_set_priority(struct thread_entry *thread, int priority)
|
|||
* Returns the current base priority for a thread.
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
int thread_get_priority(struct thread_entry *thread)
|
||||
int thread_get_priority(unsigned int thread_id)
|
||||
{
|
||||
/* Simple, quick probe. */
|
||||
if (thread == NULL)
|
||||
thread = cores[CURRENT_CORE].running;
|
||||
struct thread_entry *thread = thread_id_entry(thread_id);
|
||||
int base_priority = thread->base_priority;
|
||||
|
||||
return thread->base_priority;
|
||||
/* Simply check without locking slot. It may or may not be valid by the
|
||||
* time the function returns anyway. If all tests pass, it is the
|
||||
* correct value for when it was valid. */
|
||||
if (thread_id != THREAD_ID_CURRENT &&
|
||||
(thread->id != thread_id || thread->state == STATE_KILLED))
|
||||
base_priority = -1;
|
||||
|
||||
return base_priority;
|
||||
}
|
||||
#endif /* HAVE_PRIORITY_SCHEDULING */
|
||||
|
||||
|
@ -2924,12 +2961,16 @@ int thread_get_priority(struct thread_entry *thread)
|
|||
* virtue of the slot having a state of STATE_FROZEN.
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
void thread_thaw(struct thread_entry *thread)
|
||||
void thread_thaw(unsigned int thread_id)
|
||||
{
|
||||
struct thread_entry *thread = thread_id_entry(thread_id);
|
||||
int oldlevel = disable_irq_save();
|
||||
|
||||
LOCK_THREAD(thread);
|
||||
|
||||
if (thread->state == STATE_FROZEN)
|
||||
/* If thread is the current one, it cannot be frozen, therefore
|
||||
* there is no need to check that. */
|
||||
if (thread->id == thread_id && thread->state == STATE_FROZEN)
|
||||
core_schedule_wakeup(thread);
|
||||
|
||||
UNLOCK_THREAD(thread);
|
||||
|
@ -2940,9 +2981,9 @@ void thread_thaw(struct thread_entry *thread)
|
|||
* Return the ID of the currently executing thread.
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
struct thread_entry * thread_get_current(void)
|
||||
unsigned int thread_get_current(void)
|
||||
{
|
||||
return cores[CURRENT_CORE].running;
|
||||
return cores[CURRENT_CORE].running->id;
|
||||
}
|
||||
|
||||
#if NUM_CORES > 1
|
||||
|
@ -2967,9 +3008,10 @@ unsigned int switch_core(unsigned int new_core)
|
|||
if (current->name == THREAD_DESTRUCT)
|
||||
{
|
||||
/* Thread being killed - deactivate and let process complete */
|
||||
unsigned int id = current->id;
|
||||
UNLOCK_THREAD(current);
|
||||
restore_irq(oldlevel);
|
||||
thread_wait(current);
|
||||
thread_wait(id);
|
||||
/* Should never be reached */
|
||||
THREAD_PANICF("switch_core->D:*R", current);
|
||||
}
|
||||
|
@ -3034,6 +3076,19 @@ void init_threads(void)
|
|||
const unsigned int core = CURRENT_CORE;
|
||||
struct thread_entry *thread;
|
||||
|
||||
if (core == CPU)
|
||||
{
|
||||
/* Initialize core locks and IDs in all slots */
|
||||
int n;
|
||||
for (n = 0; n < MAXTHREADS; n++)
|
||||
{
|
||||
thread = &threads[n];
|
||||
corelock_init(&thread->waiter_cl);
|
||||
corelock_init(&thread->slot_cl);
|
||||
thread->id = THREAD_ID_INIT(n);
|
||||
}
|
||||
}
|
||||
|
||||
/* CPU will initialize first and then sleep */
|
||||
thread = find_empty_thread_slot();
|
||||
|
||||
|
@ -3060,8 +3115,6 @@ void init_threads(void)
|
|||
thread->priority = PRIORITY_USER_INTERFACE;
|
||||
rtr_add_entry(core, PRIORITY_USER_INTERFACE);
|
||||
#endif
|
||||
corelock_init(&thread->waiter_cl);
|
||||
corelock_init(&thread->slot_cl);
|
||||
|
||||
add_to_list_l(&cores[core].running, thread);
|
||||
|
||||
|
@ -3070,6 +3123,7 @@ void init_threads(void)
|
|||
thread->stack = stackbegin;
|
||||
thread->stack_size = (uintptr_t)stackend - (uintptr_t)stackbegin;
|
||||
#if NUM_CORES > 1 /* This code path will not be run on single core targets */
|
||||
/* Initialize all locking for the slots */
|
||||
/* Wait for other processors to finish their inits since create_thread
|
||||
* isn't safe to call until the kernel inits are done. The first
|
||||
* threads created in the system must of course be created by CPU. */
|
||||
|
|
|
@ -78,7 +78,7 @@ static int usb_mmc_countdown = 0;
|
|||
#ifdef USB_FULL_INIT
|
||||
static long usb_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)];
|
||||
static const char usb_thread_name[] = "usb";
|
||||
static struct thread_entry *usb_thread_entry;
|
||||
static unsigned int usb_thread_entry = 0;
|
||||
#endif
|
||||
static struct event_queue usb_queue;
|
||||
static int last_usb_status;
|
||||
|
@ -539,10 +539,10 @@ void usb_start_monitoring(void)
|
|||
#ifdef USB_DRIVER_CLOSE
|
||||
void usb_close(void)
|
||||
{
|
||||
struct thread_entry *thread = usb_thread_entry;
|
||||
usb_thread_entry = NULL;
|
||||
uintptr_t thread = usb_thread_entry;
|
||||
usb_thread_entry = 0;
|
||||
|
||||
if (thread == NULL)
|
||||
if (thread == 0)
|
||||
return;
|
||||
|
||||
tick_remove_task(usb_tick);
|
||||
|
|
|
@ -93,6 +93,38 @@ void thread_sdl_shutdown(void)
|
|||
SDL_DestroyMutex(m);
|
||||
}
|
||||
|
||||
static void new_thread_id(unsigned int slot_num,
|
||||
struct thread_entry *thread)
|
||||
{
|
||||
unsigned int version =
|
||||
(thread->id + (1u << THREAD_ID_VERSION_SHIFT))
|
||||
& THREAD_ID_VERSION_MASK;
|
||||
|
||||
if (version == 0)
|
||||
version = 1u << THREAD_ID_VERSION_SHIFT;
|
||||
|
||||
thread->id = version | (slot_num & THREAD_ID_SLOT_MASK);
|
||||
}
|
||||
|
||||
static struct thread_entry * find_empty_thread_slot(void)
|
||||
{
|
||||
struct thread_entry *thread = NULL;
|
||||
int n;
|
||||
|
||||
for (n = 0; n < MAXTHREADS; n++)
|
||||
{
|
||||
int state = threads[n].state;
|
||||
|
||||
if (state == STATE_KILLED)
|
||||
{
|
||||
thread = &threads[n];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
/* Do main thread creation in this file scope to avoid the need to double-
|
||||
return to a prior call-level which would be unaware of the fact setjmp
|
||||
was used */
|
||||
|
@ -119,6 +151,8 @@ static int thread_sdl_app_main(void *param)
|
|||
bool thread_sdl_init(void *param)
|
||||
{
|
||||
struct thread_entry *thread;
|
||||
int n;
|
||||
|
||||
memset(cores, 0, sizeof(cores));
|
||||
memset(threads, 0, sizeof(threads));
|
||||
|
||||
|
@ -130,6 +164,10 @@ bool thread_sdl_init(void *param)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Initialize all IDs */
|
||||
for (n = 0; n < MAXTHREADS; n++)
|
||||
threads[n].id = THREAD_ID_INIT(n);
|
||||
|
||||
/* Slot 0 is reserved for the main thread - initialize it here and
|
||||
then create the SDL thread - it is possible to have a quick, early
|
||||
shutdown try to access the structure. */
|
||||
|
@ -179,23 +217,11 @@ void * thread_sdl_thread_unlock(void)
|
|||
return current;
|
||||
}
|
||||
|
||||
static struct thread_entry * find_empty_thread_slot(void)
|
||||
struct thread_entry * thread_id_entry(unsigned int thread_id)
|
||||
{
|
||||
struct thread_entry *thread = NULL;
|
||||
int n;
|
||||
|
||||
for (n = 0; n < MAXTHREADS; n++)
|
||||
{
|
||||
int state = threads[n].state;
|
||||
|
||||
if (state == STATE_KILLED)
|
||||
{
|
||||
thread = &threads[n];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return thread;
|
||||
return (thread_id == THREAD_ID_CURRENT) ?
|
||||
cores[CURRENT_CORE].running :
|
||||
&threads[thread_id & THREAD_ID_SLOT_MASK];
|
||||
}
|
||||
|
||||
static void add_to_list_l(struct thread_entry **list,
|
||||
|
@ -239,9 +265,9 @@ static void remove_from_list_l(struct thread_entry **list,
|
|||
thread->l.next->l.prev = thread->l.prev;
|
||||
}
|
||||
|
||||
struct thread_entry *thread_get_current(void)
|
||||
unsigned int thread_get_current(void)
|
||||
{
|
||||
return cores[CURRENT_CORE].running;
|
||||
return cores[CURRENT_CORE].running->id;
|
||||
}
|
||||
|
||||
void switch_thread(void)
|
||||
|
@ -389,9 +415,11 @@ unsigned int thread_queue_wake(struct thread_entry **list)
|
|||
return result;
|
||||
}
|
||||
|
||||
void thread_thaw(struct thread_entry *thread)
|
||||
void thread_thaw(unsigned int thread_id)
|
||||
{
|
||||
if (thread->state == STATE_FROZEN)
|
||||
struct thread_entry *thread = thread_id_entry(thread_id);
|
||||
|
||||
if (thread->id == thread_id && thread->state == STATE_FROZEN)
|
||||
{
|
||||
thread->state = STATE_RUNNING;
|
||||
SDL_SemPost(thread->context.s);
|
||||
|
@ -441,9 +469,9 @@ int runthread(void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct thread_entry*
|
||||
create_thread(void (*function)(void), void* stack, size_t stack_size,
|
||||
unsigned flags, const char *name)
|
||||
unsigned int create_thread(void (*function)(void),
|
||||
void* stack, size_t stack_size,
|
||||
unsigned flags, const char *name)
|
||||
{
|
||||
struct thread_entry *thread;
|
||||
SDL_Thread* t;
|
||||
|
@ -455,14 +483,14 @@ struct thread_entry*
|
|||
if (thread == NULL)
|
||||
{
|
||||
DEBUGF("Failed to find thread slot\n");
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s = SDL_CreateSemaphore(0);
|
||||
if (s == NULL)
|
||||
{
|
||||
DEBUGF("Failed to create semaphore\n");
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
t = SDL_CreateThread(runthread, thread);
|
||||
|
@ -470,7 +498,7 @@ struct thread_entry*
|
|||
{
|
||||
DEBUGF("Failed to create SDL thread\n");
|
||||
SDL_DestroySemaphore(s);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
thread->stack = stack;
|
||||
|
@ -485,7 +513,7 @@ struct thread_entry*
|
|||
THREAD_SDL_DEBUGF("New Thread: %d (%s)\n",
|
||||
thread - threads, THREAD_SDL_GET_NAME(thread));
|
||||
|
||||
return thread;
|
||||
return thread->id;
|
||||
}
|
||||
|
||||
void init_threads(void)
|
||||
|
@ -501,18 +529,22 @@ void init_threads(void)
|
|||
0, THREAD_SDL_GET_NAME(&threads[0]));
|
||||
}
|
||||
|
||||
void remove_thread(struct thread_entry *thread)
|
||||
#ifndef ALLOW_REMOVE_THREAD
|
||||
static void remove_thread(unsigned int thread_id)
|
||||
#else
|
||||
void remove_thread(unsigned int thread_id)
|
||||
#endif
|
||||
{
|
||||
struct thread_entry *current = cores[CURRENT_CORE].running;
|
||||
struct thread_entry *thread = thread_id_entry(thread_id);
|
||||
|
||||
SDL_Thread *t;
|
||||
SDL_sem *s;
|
||||
|
||||
int oldlevel = disable_irq_save();
|
||||
if (thread_id != THREAD_ID_CURRENT && thread->id != thread_id)
|
||||
return;
|
||||
|
||||
if (thread == NULL)
|
||||
{
|
||||
thread = current;
|
||||
}
|
||||
int oldlevel = disable_irq_save();
|
||||
|
||||
t = thread->context.t;
|
||||
s = thread->context.s;
|
||||
|
@ -540,6 +572,7 @@ void remove_thread(struct thread_entry *thread)
|
|||
THREAD_SDL_DEBUGF("Removing thread: %d (%s)\n",
|
||||
thread - threads, THREAD_SDL_GET_NAME(thread));
|
||||
|
||||
new_thread_id(thread->id, thread);
|
||||
thread->state = STATE_KILLED;
|
||||
thread_queue_wake(&thread->queue);
|
||||
|
||||
|
@ -559,17 +592,16 @@ void remove_thread(struct thread_entry *thread)
|
|||
|
||||
void thread_exit(void)
|
||||
{
|
||||
remove_thread(NULL);
|
||||
remove_thread(THREAD_ID_CURRENT);
|
||||
}
|
||||
|
||||
void thread_wait(struct thread_entry *thread)
|
||||
void thread_wait(unsigned int thread_id)
|
||||
{
|
||||
struct thread_entry *current = cores[CURRENT_CORE].running;
|
||||
struct thread_entry *thread = thread_id_entry(thread_id);
|
||||
|
||||
if (thread == NULL)
|
||||
thread = current;
|
||||
|
||||
if (thread->state != STATE_KILLED)
|
||||
if (thread_id == THREAD_ID_CURRENT ||
|
||||
(thread->id == thread_id && thread->state != STATE_KILLED))
|
||||
{
|
||||
current->bqp = &thread->queue;
|
||||
block_thread(current);
|
||||
|
@ -583,11 +615,6 @@ int thread_stack_usage(const struct thread_entry *thread)
|
|||
(void)thread;
|
||||
}
|
||||
|
||||
unsigned thread_get_status(const struct thread_entry *thread)
|
||||
{
|
||||
return thread->state;
|
||||
}
|
||||
|
||||
/* Return name if one or ID if none */
|
||||
void thread_get_name(char *buffer, int size,
|
||||
struct thread_entry *thread)
|
||||
|
|
Loading…
Reference in a new issue