summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/buffering.c9
-rw-r--r--apps/codecs.c36
-rw-r--r--apps/codecs.h52
-rw-r--r--apps/debug_menu.c11
-rw-r--r--apps/main.c2
-rw-r--r--apps/pcmbuf.c23
-rw-r--r--apps/playback.c10
-rw-r--r--apps/plugin.c5
-rw-r--r--apps/plugin.h14
-rw-r--r--apps/plugins/mpegplayer/audio_thread.c6
-rw-r--r--apps/plugins/mpegplayer/disk_buf.c4
-rw-r--r--apps/plugins/mpegplayer/stream_mgr.c4
-rw-r--r--apps/plugins/mpegplayer/video_thread.c6
-rw-r--r--apps/voice_thread.c4
14 files changed, 100 insertions, 86 deletions
diff --git a/apps/buffering.c b/apps/buffering.c
index 64f522c..0cb428c 100644
--- a/apps/buffering.c
+++ b/apps/buffering.c
@@ -1446,16 +1446,21 @@ void buffering_thread(void)
void buffering_init(void) {
mutex_init(&llist_mutex);
+#ifdef HAVE_PRIORITY_SCHEDULING
+ /* This behavior not safe atm */
+ mutex_set_preempt(&llist_mutex, false);
+#endif
conf_watermark = BUFFERING_DEFAULT_WATERMARK;
queue_init(&buffering_queue, true);
- queue_enable_queue_send(&buffering_queue, &buffering_queue_sender_list);
-
buffering_thread_p = 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);
}
/* Initialise the buffering subsystem */
diff --git a/apps/codecs.c b/apps/codecs.c
index dfae463..f2c7452 100644
--- a/apps/codecs.c
+++ b/apps/codecs.c
@@ -76,6 +76,7 @@ struct codec_api ci = {
false, /* stop_codec */
0, /* new_track */
0, /* seek_time */
+ NULL, /* struct dsp_config *dsp */
NULL, /* get_codec_memory */
NULL, /* pcmbuf_insert */
NULL, /* set_elapsed */
@@ -95,6 +96,23 @@ struct codec_api ci = {
PREFIX(sleep),
yield,
+#if NUM_CORES > 1
+ create_thread,
+ thread_thaw,
+ thread_wait,
+ semaphore_init,
+ semaphore_wait,
+ semaphore_release,
+ event_init,
+ event_wait,
+ event_set_state,
+#endif
+
+#ifdef CACHE_FUNCTIONS_AS_CALL
+ flush_icache,
+ invalidate_icache,
+#endif
+
/* strings and memory */
strcpy,
strncpy,
@@ -147,24 +165,6 @@ struct codec_api ci = {
/* new stuff at the end, sort into place next time
the API gets incompatible */
-#ifdef CACHE_FUNCTIONS_AS_CALL
- flush_icache,
- invalidate_icache,
-#endif
-
- NULL, /* struct dsp_config *dsp */
-
-#if NUM_CORES > 1
- create_thread,
- thread_thaw,
- thread_wait,
- semaphore_init,
- semaphore_wait,
- semaphore_release,
- event_init,
- event_wait,
- event_set_state,
-#endif
};
void codec_get_full_path(char *path, const char *codec_root_fn)
diff --git a/apps/codecs.h b/apps/codecs.h
index ad6b831..fb5675f 100644
--- a/apps/codecs.h
+++ b/apps/codecs.h
@@ -80,12 +80,12 @@
#define CODEC_ENC_MAGIC 0x52454E43 /* RENC */
/* increase this every time the api struct changes */
-#define CODEC_API_VERSION 22
+#define CODEC_API_VERSION 23
/* 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 22
+#define CODEC_MIN_API_VERSION 23
/* codec return codes */
enum codec_status {
@@ -118,6 +118,9 @@ struct codec_api {
/* If seek_time != 0, codec should seek to that song position (in ms)
if codec supports seeking. */
long seek_time;
+
+ /* The dsp instance to be used for audio output */
+ struct dsp_config *dsp;
/* Returns buffer to malloc array. Only codeclib should need this. */
void* (*get_codec_memory)(size_t *size);
@@ -160,6 +163,28 @@ struct codec_api {
void (*PREFIX(sleep))(int ticks);
void (*yield)(void);
+#if NUM_CORES > 1
+ 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));
+
+ void (*thread_thaw)(struct thread_entry *thread);
+ void (*thread_wait)(struct thread_entry *thread);
+ void (*semaphore_init)(struct semaphore *s, int max, int start);
+ void (*semaphore_wait)(struct semaphore *s);
+ void (*semaphore_release)(struct semaphore *s);
+ void (*event_init)(struct event *e, unsigned int flags);
+ void (*event_wait)(struct event *e, unsigned int for_state);
+ void (*event_set_state)(struct event *e, unsigned int state);
+#endif /* NUM_CORES */
+
+#ifdef CACHE_FUNCTIONS_AS_CALL
+ void (*flush_icache)(void);
+ void (*invalidate_icache)(void);
+#endif
+
/* strings and memory */
char* (*strcpy)(char *dst, const char *src);
char* (*strncpy)(char *dst, const char *src, size_t length);
@@ -218,29 +243,6 @@ struct codec_api {
/* new stuff at the end, sort into place next time
the API gets incompatible */
-#ifdef CACHE_FUNCTIONS_AS_CALL
- void (*flush_icache)(void);
- void (*invalidate_icache)(void);
-#endif
-
- struct dsp_config *dsp;
-
-#if NUM_CORES > 1
- struct thread_entry *
- (*create_thread)(void (*function)(void), void* stack,
- int 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 (*semaphore_init)(struct semaphore *s, int max, int start);
- void (*semaphore_wait)(struct semaphore *s);
- void (*semaphore_release)(struct semaphore *s);
- void (*event_init)(struct event *e, unsigned int flags);
- void (*event_wait)(struct event *e, unsigned int for_state);
- void (*event_set_state)(struct event *e, unsigned int state);
-#endif /* NUM_CORES */
};
/* codec header */
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index d865f12..fc509ce 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -127,11 +127,6 @@ static char thread_status_char(unsigned status)
[STATE_KILLED] = 'K',
};
-#if NUM_CORES > 1
- if (status == STATE_BUSY) /* Not a state index */
- return '.';
-#endif
-
if (status > THREAD_NUM_STATES)
status = THREAD_NUM_STATES;
@@ -166,15 +161,15 @@ static char* threads_getname(int selected_item, void * data, char *buffer)
thread_get_name(name, 32, thread);
snprintf(buffer, MAX_PATH,
- "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d ") "%2d%% %s",
+ "%2d: " IF_COP("(%d) ") "%c%c " IF_PRIO("%d %d ") "%2d%% %s",
selected_item,
IF_COP(thread->core,)
#ifdef HAVE_SCHEDULER_BOOSTCTRL
- (thread->boosted) ? '+' :
+ (thread->cpu_boost) ? '+' :
#endif
((thread->state == STATE_RUNNING) ? '*' : ' '),
thread_status_char(thread->state),
- IF_PRIO(thread->priority,)
+ IF_PRIO(thread->base_priority, thread->priority, )
thread_stack_usage(thread), name);
return buffer;
diff --git a/apps/main.c b/apps/main.c
index 5dd92e5..a3a2241 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -270,7 +270,7 @@ static void init_tagcache(void)
static void init(void)
{
- init_threads();
+ kernel_init();
buffer_init();
set_irq_level(0);
lcd_init();
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index 8153118..8f16c90 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -116,7 +116,7 @@ static bool low_latency_mode = false;
static bool pcmbuf_flush;
#ifdef HAVE_PRIORITY_SCHEDULING
-static int codec_thread_priority = 0;
+static int codec_thread_priority = PRIORITY_PLAYBACK;
#endif
extern struct thread_entry *codec_thread_p;
@@ -256,18 +256,21 @@ static void boost_codec_thread(bool boost)
* will starve if the codec thread's priority is boosted. */
if (boost)
{
- if (codec_thread_priority == 0)
+ int priority = (PRIORITY_PLAYBACK - PRIORITY_PLAYBACK_MAX)*pcmbuf_unplayed_bytes
+ / (2*NATIVE_FREQUENCY) + PRIORITY_PLAYBACK_MAX;
+
+ if (priority != codec_thread_priority)
{
- codec_thread_priority = thread_set_priority(
- codec_thread_p, PRIORITY_REALTIME);
- voice_thread_set_priority(PRIORITY_REALTIME);
+ codec_thread_priority = priority;
+ thread_set_priority(codec_thread_p, priority);
+ voice_thread_set_priority(priority);
}
}
- else if (codec_thread_priority != 0)
+ else if (codec_thread_priority != PRIORITY_PLAYBACK)
{
- thread_set_priority(codec_thread_p, codec_thread_priority);
- voice_thread_set_priority(codec_thread_priority);
- codec_thread_priority = 0;
+ thread_set_priority(codec_thread_p, PRIORITY_PLAYBACK);
+ voice_thread_set_priority(PRIORITY_PLAYBACK);
+ codec_thread_priority = PRIORITY_PLAYBACK;
}
}
#endif /* HAVE_PRIORITY_SCHEDULING */
@@ -818,7 +821,7 @@ static bool prepare_insert(size_t length)
if (low_latency_mode)
{
/* 1/4s latency. */
- if (pcmbuf_unplayed_bytes > NATIVE_FREQUENCY * 4 / 4
+ if (pcmbuf_unplayed_bytes > NATIVE_FREQUENCY * 4 / 2
&& pcm_is_playing())
return false;
}
diff --git a/apps/playback.c b/apps/playback.c
index 7eecd23..9005b34 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -2549,9 +2549,7 @@ void audio_init(void)
to send messages. Thread creation will be delayed however so nothing
starts running until ready if something yields such as talk_init. */
queue_init(&audio_queue, true);
- queue_enable_queue_send(&audio_queue, &audio_queue_sender_list);
queue_init(&codec_queue, false);
- queue_enable_queue_send(&codec_queue, &codec_queue_sender_list);
queue_init(&pcmbuf_queue, false);
pcm_init();
@@ -2587,11 +2585,17 @@ void audio_init(void)
codec_thread_name IF_PRIO(, PRIORITY_PLAYBACK)
IF_COP(, CPU));
+ queue_enable_queue_send(&codec_queue, &codec_queue_sender_list,
+ codec_thread_p);
+
audio_thread_p = create_thread(audio_thread, audio_stack,
sizeof(audio_stack), CREATE_THREAD_FROZEN,
- audio_thread_name IF_PRIO(, PRIORITY_SYSTEM)
+ audio_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
IF_COP(, CPU));
+ queue_enable_queue_send(&audio_queue, &audio_queue_sender_list,
+ audio_thread_p);
+
#ifdef PLAYBACK_VOICE
voice_thread_init();
#endif
diff --git a/apps/plugin.c b/apps/plugin.c
index 57f836c..db9bd25 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -253,15 +253,12 @@ static const struct plugin_api rockbox_api = {
/* kernel/ system */
PREFIX(sleep),
yield,
-#ifdef HAVE_PRIORITY_SCHEDULING
- priority_yield,
-#endif
&current_tick,
default_event_handler,
default_event_handler_ex,
threads,
create_thread,
- remove_thread,
+ thread_exit,
thread_wait,
#if (CONFIG_CODEC == SWCODEC)
mutex_init,
diff --git a/apps/plugin.h b/apps/plugin.h
index cd42656..5762473 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -119,12 +119,12 @@
#define PLUGIN_MAGIC 0x526F634B /* RocK */
/* increase this every time the api struct changes */
-#define PLUGIN_API_VERSION 100
+#define PLUGIN_API_VERSION 101
/* 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 100
+#define PLUGIN_MIN_API_VERSION 101
/* plugin return codes */
enum plugin_status {
@@ -351,19 +351,16 @@ struct plugin_api {
/* kernel/ system */
void (*PREFIX(sleep))(int ticks);
void (*yield)(void);
-#ifdef HAVE_PRIORITY_SCHEDULING
- void (*priority_yield)(void);
-#endif
volatile long* current_tick;
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,
- int stack_size, unsigned flags,
+ size_t stack_size, unsigned flags,
const char *name
IF_PRIO(, int priority)
IF_COP(, unsigned int core));
- void (*remove_thread)(struct thread_entry *thread);
+ void (*thread_exit)(void);
void (*thread_wait)(struct thread_entry *thread);
#if CONFIG_CODEC == SWCODEC
void (*mutex_init)(struct mutex *m);
@@ -405,7 +402,8 @@ struct plugin_api {
int ticks);
#if CONFIG_CODEC == SWCODEC
void (*queue_enable_queue_send)(struct event_queue *q,
- struct queue_sender_list *send);
+ struct queue_sender_list *send,
+ struct thread_entry *owner);
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,
diff --git a/apps/plugins/mpegplayer/audio_thread.c b/apps/plugins/mpegplayer/audio_thread.c
index 2bb766a..7d2f849 100644
--- a/apps/plugins/mpegplayer/audio_thread.c
+++ b/apps/plugins/mpegplayer/audio_thread.c
@@ -714,12 +714,14 @@ bool audio_thread_init(void)
/* Start the audio thread */
audio_str.hdr.q = &audio_str_queue;
rb->queue_init(audio_str.hdr.q, false);
- rb->queue_enable_queue_send(audio_str.hdr.q, &audio_str_queue_send);
/* One-up on the priority since the core DSP over-yields internally */
audio_str.thread = rb->create_thread(
audio_thread, audio_stack, audio_stack_size, 0,
- "mpgaudio" IF_PRIO(,PRIORITY_PLAYBACK-1) IF_COP(, CPU));
+ "mpgaudio" IF_PRIO(,PRIORITY_PLAYBACK-4) IF_COP(, CPU));
+
+ rb->queue_enable_queue_send(audio_str.hdr.q, &audio_str_queue_send,
+ audio_str.thread);
if (audio_str.thread == NULL)
return false;
diff --git a/apps/plugins/mpegplayer/disk_buf.c b/apps/plugins/mpegplayer/disk_buf.c
index a408b90..289918f 100644
--- a/apps/plugins/mpegplayer/disk_buf.c
+++ b/apps/plugins/mpegplayer/disk_buf.c
@@ -837,7 +837,6 @@ bool disk_buf_init(void)
disk_buf.q = &disk_buf_queue;
rb->queue_init(disk_buf.q, false);
- rb->queue_enable_queue_send(disk_buf.q, &disk_buf_queue_send);
disk_buf.state = TSTATE_EOS;
disk_buf.status = STREAM_STOPPED;
@@ -886,6 +885,9 @@ bool disk_buf_init(void)
disk_buf_thread, disk_buf_stack, sizeof(disk_buf_stack), 0,
"mpgbuffer" IF_PRIO(, PRIORITY_BUFFERING) IF_COP(, CPU));
+ rb->queue_enable_queue_send(disk_buf.q, &disk_buf_queue_send,
+ disk_buf.thread);
+
if (disk_buf.thread == NULL)
return false;
diff --git a/apps/plugins/mpegplayer/stream_mgr.c b/apps/plugins/mpegplayer/stream_mgr.c
index 9da664e..b962c5b 100644
--- a/apps/plugins/mpegplayer/stream_mgr.c
+++ b/apps/plugins/mpegplayer/stream_mgr.c
@@ -987,7 +987,6 @@ int stream_init(void)
stream_mgr.q = &stream_mgr_queue;
rb->queue_init(stream_mgr.q, false);
- rb->queue_enable_queue_send(stream_mgr.q, &stream_mgr_queue_send);
/* sets audiosize and returns buffer pointer */
mem = rb->plugin_get_audio_buffer(&memsize);
@@ -1028,6 +1027,9 @@ int stream_init(void)
stream_mgr_thread_stack, sizeof(stream_mgr_thread_stack),
0, "mpgstream_mgr" IF_PRIO(, PRIORITY_SYSTEM) IF_COP(, CPU));
+ rb->queue_enable_queue_send(stream_mgr.q, &stream_mgr_queue_send,
+ stream_mgr.thread);
+
if (stream_mgr.thread == NULL)
{
rb->splash(HZ, "Could not create stream manager thread!");
diff --git a/apps/plugins/mpegplayer/video_thread.c b/apps/plugins/mpegplayer/video_thread.c
index 6508d28..d16eb77 100644
--- a/apps/plugins/mpegplayer/video_thread.c
+++ b/apps/plugins/mpegplayer/video_thread.c
@@ -955,7 +955,7 @@ static void video_thread(void)
else
{
/* Just a little left - spin and be accurate */
- rb->priority_yield();
+ rb->yield();
if (str_have_msg(&video_str))
goto message_wait;
}
@@ -998,13 +998,15 @@ bool video_thread_init(void)
video_str.hdr.q = &video_str_queue;
rb->queue_init(video_str.hdr.q, false);
- rb->queue_enable_queue_send(video_str.hdr.q, &video_str_queue_send);
/* We put the video thread on another processor for multi-core targets. */
video_str.thread = rb->create_thread(
video_thread, video_stack, VIDEO_STACKSIZE, 0,
"mpgvideo" IF_PRIO(,PRIORITY_PLAYBACK) IF_COP(, COP));
+ rb->queue_enable_queue_send(video_str.hdr.q, &video_str_queue_send,
+ video_str.thread);
+
if (video_str.thread == NULL)
return false;
diff --git a/apps/voice_thread.c b/apps/voice_thread.c
index 7bf52d4..6e70f43 100644
--- a/apps/voice_thread.c
+++ b/apps/voice_thread.c
@@ -424,12 +424,14 @@ void voice_thread_init(void)
{
logf("Starting voice thread");
queue_init(&voice_queue, false);
- queue_enable_queue_send(&voice_queue, &voice_queue_sender_list);
mutex_init(&voice_mutex);
event_init(&voice_event, STATE_SIGNALED | EVENT_MANUAL);
voice_thread_p = 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_init */
/* Unfreeze the voice thread */