diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2006-09-16 16:18:11 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2006-09-16 16:18:11 +0000 |
commit | a85044bf9eaa0a7206c1978d3cfd57ab2d7fae2f (patch) | |
tree | a30695ed540bf32365d577f46398f712c7a494c4 /apps/playback.c | |
parent | baf5494341cdd6cdb9590e21d429920b9bc4a2c6 (diff) | |
download | rockbox-a85044bf9eaa0a7206c1978d3cfd57ab2d7fae2f.tar.gz rockbox-a85044bf9eaa0a7206c1978d3cfd57ab2d7fae2f.zip |
New scheduler, with priorities for swcodec platforms. Frequent task
switching should be more efficient and tasks are stored in linked
lists to eliminate unnecessary task switching to improve performance.
Audio should no longer skip on swcodec targets caused by too CPU
hungry UI thread or background threads.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10958 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/playback.c')
-rw-r--r-- | apps/playback.c | 45 |
1 files changed, 26 insertions, 19 deletions
diff --git a/apps/playback.c b/apps/playback.c index 352c99b390..33667cc656 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -176,7 +176,7 @@ static char *voicebuf; | |||
176 | static size_t voice_remaining; | 176 | static size_t voice_remaining; |
177 | static bool voice_is_playing; | 177 | static bool voice_is_playing; |
178 | static void (*voice_getmore)(unsigned char** start, int* size); | 178 | static void (*voice_getmore)(unsigned char** start, int* size); |
179 | static int voice_thread_num = -1; | 179 | static struct thread_entry *voice_thread_p = NULL; |
180 | 180 | ||
181 | /* Is file buffer currently being refilled? */ | 181 | /* Is file buffer currently being refilled? */ |
182 | static volatile bool filling IDATA_ATTR; | 182 | static volatile bool filling IDATA_ATTR; |
@@ -267,6 +267,8 @@ static struct event_queue codec_queue; | |||
267 | static long codec_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)] | 267 | static long codec_stack[(DEFAULT_STACK_SIZE + 0x2000)/sizeof(long)] |
268 | IBSS_ATTR; | 268 | IBSS_ATTR; |
269 | static const char codec_thread_name[] = "codec"; | 269 | static const char codec_thread_name[] = "codec"; |
270 | /* For modifying thread priority later. */ | ||
271 | struct thread_entry *codec_thread_p; | ||
270 | 272 | ||
271 | /* Voice thread */ | 273 | /* Voice thread */ |
272 | static struct event_queue voice_queue; | 274 | static struct event_queue voice_queue; |
@@ -628,13 +630,13 @@ void audio_preinit(void) | |||
628 | 630 | ||
629 | mutex_init(&mutex_codecthread); | 631 | mutex_init(&mutex_codecthread); |
630 | 632 | ||
631 | queue_init(&audio_queue); | 633 | queue_init(&audio_queue, true); |
632 | queue_init(&codec_queue); | 634 | queue_init(&codec_queue, true); |
633 | /* clear, not init to create a private queue */ | 635 | /* create a private queue */ |
634 | queue_clear(&codec_callback_queue); | 636 | queue_init(&codec_callback_queue, false); |
635 | 637 | ||
636 | create_thread(audio_thread, audio_stack, sizeof(audio_stack), | 638 | create_thread(audio_thread, audio_stack, sizeof(audio_stack), |
637 | audio_thread_name); | 639 | audio_thread_name IF_PRIO(, PRIORITY_BUFFERING)); |
638 | } | 640 | } |
639 | 641 | ||
640 | void audio_init(void) | 642 | void audio_init(void) |
@@ -648,14 +650,14 @@ void voice_init(void) | |||
648 | if (!filebuf) | 650 | if (!filebuf) |
649 | return; /* Audio buffers not yet set up */ | 651 | return; /* Audio buffers not yet set up */ |
650 | 652 | ||
651 | if (voice_thread_num >= 0) | 653 | if (voice_thread_p) |
652 | { | 654 | { |
653 | logf("Terminating voice codec"); | 655 | logf("Terminating voice codec"); |
654 | remove_thread(voice_thread_num); | 656 | remove_thread(voice_thread_p); |
655 | if (current_codec == CODEC_IDX_VOICE) | 657 | if (current_codec == CODEC_IDX_VOICE) |
656 | mutex_unlock(&mutex_codecthread); | 658 | mutex_unlock(&mutex_codecthread); |
657 | queue_delete(&voice_queue); | 659 | queue_delete(&voice_queue); |
658 | voice_thread_num = -1; | 660 | voice_thread_p = NULL; |
659 | voice_codec_loaded = false; | 661 | voice_codec_loaded = false; |
660 | } | 662 | } |
661 | 663 | ||
@@ -663,9 +665,10 @@ void voice_init(void) | |||
663 | return; | 665 | return; |
664 | 666 | ||
665 | logf("Starting voice codec"); | 667 | logf("Starting voice codec"); |
666 | queue_init(&voice_queue); | 668 | queue_init(&voice_queue, true); |
667 | voice_thread_num = create_thread(voice_thread, voice_stack, | 669 | voice_thread_p = create_thread(voice_thread, voice_stack, |
668 | sizeof(voice_stack), voice_thread_name); | 670 | sizeof(voice_stack), voice_thread_name |
671 | IF_PRIO(, PRIORITY_PLAYBACK)); | ||
669 | 672 | ||
670 | while (!voice_codec_loaded) | 673 | while (!voice_codec_loaded) |
671 | yield(); | 674 | yield(); |
@@ -1740,7 +1743,7 @@ static void codec_thread(void) | |||
1740 | #endif | 1743 | #endif |
1741 | 1744 | ||
1742 | #ifndef SIMULATOR | 1745 | #ifndef SIMULATOR |
1743 | case SYS_USB_CONNECTED: | 1746 | case SYS_USB_CONNECTED: |
1744 | LOGFQUEUE("codec < SYS_USB_CONNECTED"); | 1747 | LOGFQUEUE("codec < SYS_USB_CONNECTED"); |
1745 | queue_clear(&codec_queue); | 1748 | queue_clear(&codec_queue); |
1746 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | 1749 | usb_acknowledge(SYS_USB_CONNECTED_ACK); |
@@ -1982,13 +1985,15 @@ static bool audio_yield_codecs(void) | |||
1982 | { | 1985 | { |
1983 | yield(); | 1986 | yield(); |
1984 | 1987 | ||
1985 | if (!queue_empty(&audio_queue)) return true; | 1988 | if (!queue_empty(&audio_queue)) |
1989 | return true; | ||
1986 | 1990 | ||
1987 | while ((pcmbuf_is_crossfade_active() || pcmbuf_is_lowdata()) | 1991 | while ((pcmbuf_is_crossfade_active() || pcmbuf_is_lowdata()) |
1988 | && !ci.stop_codec && playing && !audio_filebuf_is_lowdata()) | 1992 | && !ci.stop_codec && playing && !audio_filebuf_is_lowdata()) |
1989 | { | 1993 | { |
1990 | sleep(1); | 1994 | sleep(1); |
1991 | if (!queue_empty(&audio_queue)) return true; | 1995 | if (!queue_empty(&audio_queue)) |
1996 | return true; | ||
1992 | } | 1997 | } |
1993 | 1998 | ||
1994 | return false; | 1999 | return false; |
@@ -3178,8 +3183,9 @@ static void audio_playback_init(void) | |||
3178 | id3_voice.frequency = 11200; | 3183 | id3_voice.frequency = 11200; |
3179 | id3_voice.length = 1000000L; | 3184 | id3_voice.length = 1000000L; |
3180 | 3185 | ||
3181 | create_thread(codec_thread, codec_stack, sizeof(codec_stack), | 3186 | codec_thread_p = create_thread(codec_thread, codec_stack, |
3182 | codec_thread_name); | 3187 | sizeof(codec_stack), |
3188 | codec_thread_name IF_PRIO(, PRIORITY_PLAYBACK)); | ||
3183 | 3189 | ||
3184 | while (1) | 3190 | while (1) |
3185 | { | 3191 | { |
@@ -3213,7 +3219,8 @@ static void audio_thread(void) | |||
3213 | /* At first initialize audio system in background. */ | 3219 | /* At first initialize audio system in background. */ |
3214 | audio_playback_init(); | 3220 | audio_playback_init(); |
3215 | 3221 | ||
3216 | while (1) { | 3222 | while (1) |
3223 | { | ||
3217 | if (filling) | 3224 | if (filling) |
3218 | { | 3225 | { |
3219 | queue_wait_w_tmo(&audio_queue, &ev, 0); | 3226 | queue_wait_w_tmo(&audio_queue, &ev, 0); |
@@ -3221,7 +3228,7 @@ static void audio_thread(void) | |||
3221 | ev.id = Q_AUDIO_FILL_BUFFER; | 3228 | ev.id = Q_AUDIO_FILL_BUFFER; |
3222 | } | 3229 | } |
3223 | else | 3230 | else |
3224 | queue_wait_w_tmo(&audio_queue, &ev, HZ); | 3231 | queue_wait_w_tmo(&audio_queue, &ev, HZ/2); |
3225 | 3232 | ||
3226 | switch (ev.id) { | 3233 | switch (ev.id) { |
3227 | case Q_AUDIO_FILL_BUFFER: | 3234 | case Q_AUDIO_FILL_BUFFER: |