diff options
| author | Michael Sevakis <jethead71@rockbox.org> | 2008-01-24 13:35:13 +0000 |
|---|---|---|
| committer | Michael Sevakis <jethead71@rockbox.org> | 2008-01-24 13:35:13 +0000 |
| commit | ef1f7d3bf980639d656ff6794ecdd0eb64207420 (patch) | |
| tree | 64d4dcdbafcdbb2215e97d5591d6fbc18af040ec /apps | |
| parent | 4cfae09f02f119dceb8e90ce439dbf43eb5203e7 (diff) | |
| download | rockbox-ef1f7d3bf980639d656ff6794ecdd0eb64207420.zip rockbox-ef1f7d3bf980639d656ff6794ecdd0eb64207420.tar.gz rockbox-ef1f7d3bf980639d656ff6794ecdd0eb64207420.tar.bz2 rockbox-ef1f7d3bf980639d656ff6794ecdd0eb64207420.tar.xz | |
SPC Codec: Ensure no crash occurs on load failure which could cause emulation to be run without a program loaded on dual core (DSP wasn't initialized yet). The load failures come from core buffering not having the atomic audio file fully loaded before the codec requests the buffer (it gets as many bytes as can be provided) which IMHO isn't very atomic :). Changes in thread execution order after dumping spinlocks for general use simply revealed the buffering race condition. No fix for that will be hacked into the codec itself but should be fixed in the core. Add my copyright to files I had a significant part in developing per request of Adam Gashlin.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16154 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
| -rw-r--r-- | apps/codecs/spc.c | 37 | ||||
| -rw-r--r-- | apps/codecs/spc/spc_codec.h | 1 | ||||
| -rw-r--r-- | apps/codecs/spc/spc_dsp.c | 3 | ||||
| -rw-r--r-- | apps/codecs/spc/spc_emu.c | 6 |
4 files changed, 32 insertions, 15 deletions
diff --git a/apps/codecs/spc.c b/apps/codecs/spc.c index 33618f1..0a608df 100644 --- a/apps/codecs/spc.c +++ b/apps/codecs/spc.c @@ -7,6 +7,7 @@ * \/ \/ \/ \/ \/ * $Id$ * + * Copyright (C) 2007-2008 Michael Sevakis (jhMikeS) * Copyright (C) 2006-2007 Adam Gashlin (hcs) * Copyright (C) 2004-2007 Shay Green (blargg) * Copyright (C) 2002 Brad Martin @@ -278,8 +279,12 @@ static intptr_t emu_thread_send_msg(long id, intptr_t data) chunk->data = data; /* Release it to the emu thread */ samples_release_rdbuf(); - /* Wait for a response */ - ci->event_wait(&sample_queue.emu_evt_reply, STATE_SIGNALED); + + if (id != SPC_EMU_QUIT) { + /* Wait for a response */ + ci->event_wait(&sample_queue.emu_evt_reply, STATE_SIGNALED); + } + return sample_queue.retval; } @@ -298,16 +303,19 @@ static bool emu_thread_process_msg(struct sample_queue_chunk *chunk) invalidate_icache(); SPC_Init(&spc_emu); sample_queue.retval = SPC_load_spc(&spc_emu, ld->buf, ld->size); + + /* Empty the audio queue */ + /* This is a dirty hack a timeout based wait would make unnescessary but + still safe because the other thread is known to be waiting for a reply + and is not using the objects. */ + ci->semaphore_init(&sample_queue.emu_sem_tail, 2, 2); + ci->semaphore_init(&sample_queue.emu_sem_head, 2, 0); + sample_queue.head = sample_queue.tail = 0; } - /* Empty the audio queue */ - /* This is a dirty hack a timeout based wait would make unnescessary but - still safe because the other thread is known to be waiting for a reply - and is not using the objects. */ - ci->semaphore_init(&sample_queue.emu_sem_tail, 2, 2); - ci->semaphore_init(&sample_queue.emu_sem_head, 2, 0); - sample_queue.head = sample_queue.tail = 0; - ci->event_set_state(&sample_queue.emu_evt_reply, STATE_SIGNALED); + if (id != SPC_EMU_QUIT) { + ci->event_set_state(&sample_queue.emu_evt_reply, STATE_SIGNALED); + } return ret; } @@ -373,9 +381,12 @@ static inline int load_spc_buffer(uint8_t *buf, size_t size) static inline void spc_emu_quit(void) { - emu_thread_send_msg(SPC_EMU_QUIT, 0); - /* Wait for emu thread to be killed */ - ci->thread_wait(emu_thread_p); + if (emu_thread_p != NULL) { + emu_thread_send_msg(SPC_EMU_QUIT, 0); + /* Wait for emu thread to be killed */ + ci->thread_wait(emu_thread_p); + invalidate_icache(); + } } static inline bool spc_play_get_samples(int32_t **samples) diff --git a/apps/codecs/spc/spc_codec.h b/apps/codecs/spc/spc_codec.h index 013f536..a18aece 100644 --- a/apps/codecs/spc/spc_codec.h +++ b/apps/codecs/spc/spc_codec.h @@ -7,6 +7,7 @@ * \/ \/ \/ \/ \/ * $Id$ * + * Copyright (C) 2007-2008 Michael Sevakis (jhMikeS) * Copyright (C) 2006-2007 Adam Gashlin (hcs) * Copyright (C) 2004-2007 Shay Green (blargg) * Copyright (C) 2002 Brad Martin diff --git a/apps/codecs/spc/spc_dsp.c b/apps/codecs/spc/spc_dsp.c index 19986fd..dda80e9 100644 --- a/apps/codecs/spc/spc_dsp.c +++ b/apps/codecs/spc/spc_dsp.c @@ -7,6 +7,7 @@ * \/ \/ \/ \/ \/ * $Id$ * + * Copyright (C) 2007-2008 Michael Sevakis (jhMikeS) * Copyright (C) 2006-2007 Adam Gashlin (hcs) * Copyright (C) 2004-2007 Shay Green (blargg) * Copyright (C) 2002 Brad Martin @@ -31,7 +32,7 @@ int32_t fir_buf[FIR_BUF_CNT] #endif #if SPC_BRRCACHE /* a little extra for samples that go past end */ -int16_t BRRcache [BRR_CACHE_SIZE]; +int16_t BRRcache [BRR_CACHE_SIZE] CACHEALIGN_ATTR; #endif void DSP_write( struct Spc_Dsp* this, int i, int data ) diff --git a/apps/codecs/spc/spc_emu.c b/apps/codecs/spc/spc_emu.c index 30aaf5d..bd9c005 100644 --- a/apps/codecs/spc/spc_emu.c +++ b/apps/codecs/spc/spc_emu.c @@ -27,7 +27,7 @@ /* DSP Based on Brad Martin's OpenSPC DSP emulator */ /* tag reading from sexyspc by John Brawn (John_Brawn@yahoo.com) and others */ -struct cpu_ram_t ram; +struct cpu_ram_t ram CACHEALIGN_ATTR; /**************** Timers ****************/ @@ -76,6 +76,10 @@ void SPC_Init( THIS ) this->boot_rom [sizeof this->boot_rom - 2] = 0xC0; this->boot_rom [sizeof this->boot_rom - 1] = 0xFF; ci->memset( this->boot_rom, 0, sizeof this->boot_rom - 2 ); + + /* Have DSP in a defined state in case EMU is run and hasn't loaded + * a program yet */ + DSP_reset(&this->dsp); } static void SPC_load_state( THIS, struct cpu_regs_t const* cpu_state, |