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