diff options
Diffstat (limited to 'apps')
| -rw-r--r-- | apps/buffering.c | 9 | ||||
| -rw-r--r-- | apps/codecs.c | 36 | ||||
| -rw-r--r-- | apps/codecs.h | 52 | ||||
| -rw-r--r-- | apps/debug_menu.c | 11 | ||||
| -rw-r--r-- | apps/main.c | 2 | ||||
| -rw-r--r-- | apps/pcmbuf.c | 23 | ||||
| -rw-r--r-- | apps/playback.c | 10 | ||||
| -rw-r--r-- | apps/plugin.c | 5 | ||||
| -rw-r--r-- | apps/plugin.h | 14 | ||||
| -rw-r--r-- | apps/plugins/mpegplayer/audio_thread.c | 6 | ||||
| -rw-r--r-- | apps/plugins/mpegplayer/disk_buf.c | 4 | ||||
| -rw-r--r-- | apps/plugins/mpegplayer/stream_mgr.c | 4 | ||||
| -rw-r--r-- | apps/plugins/mpegplayer/video_thread.c | 6 | ||||
| -rw-r--r-- | apps/voice_thread.c | 4 |
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 ¤t_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 */ |