summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2010-12-28 11:33:55 +0000
committerMichael Sevakis <jethead71@rockbox.org>2010-12-28 11:33:55 +0000
commit4d39c9fb2e54eb33736fb1ee45b34dc335a49ea1 (patch)
tree3481cb44ef7299d8cd95eb9b697a6169d1716812
parent1f06ca41e889848934b52c94c9d6f58dfe1f39f1 (diff)
downloadrockbox-4d39c9fb2e54eb33736fb1ee45b34dc335a49ea1.zip
rockbox-4d39c9fb2e54eb33736fb1ee45b34dc335a49ea1.tar.gz
rockbox-4d39c9fb2e54eb33736fb1ee45b34dc335a49ea1.tar.bz2
rockbox-4d39c9fb2e54eb33736fb1ee45b34dc335a49ea1.tar.xz
UISimulator: Need a 'while' not an 'if' in sim_enter_irq_handler. Add comments explaining things.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28916 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/hosted/sdl/kernel-sdl.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/firmware/target/hosted/sdl/kernel-sdl.c b/firmware/target/hosted/sdl/kernel-sdl.c
index 5c13352..0b41685 100644
--- a/firmware/target/hosted/sdl/kernel-sdl.c
+++ b/firmware/target/hosted/sdl/kernel-sdl.c
@@ -39,8 +39,14 @@ static SDL_cond *sim_thread_cond;
/* Mutex to serialize changing levels and exclude other threads while
* inside a handler */
static SDL_mutex *sim_irq_mtx;
+/* Level: 0 = enabled, not 0 = disabled */
static int interrupt_level = HIGHEST_IRQ_LEVEL;
+/* How many handers waiting? Not strictly needed because CondSignal is a
+ * noop if no threads were waiting but it filters-out calls to functions
+ * with higher overhead and provides info when debugging. */
static int handlers_pending = 0;
+/* 1 = executing a handler; prevents CondSignal calls in set_irq_level
+ * while in a handler */
static int status_reg = 0;
/* Nescessary logic:
@@ -57,7 +63,8 @@ int set_irq_level(int level)
if (status_reg == 0 && level == 0 && oldlevel != 0)
{
- /* Not in a handler and "interrupts" are being reenabled */
+ /* Not in a handler and "interrupts" are going from disabled to
+ * enabled; signal any pending handlers still waiting */
if (handlers_pending > 0)
SDL_CondSignal(sim_thread_cond);
}
@@ -73,17 +80,19 @@ void sim_enter_irq_handler(void)
SDL_LockMutex(sim_irq_mtx);
handlers_pending++;
- if(interrupt_level != 0)
- {
- /* "Interrupts" are disabled. Wait for reenable */
+ /* Check each time before proceeding: disabled->enabled->...->disabled
+ * is possible on an app thread before a handler thread is ever granted
+ * the mutex; a handler can also leave "interrupts" disabled during
+ * its execution */
+ while (interrupt_level != 0)
SDL_CondWait(sim_thread_cond, sim_irq_mtx);
- }
status_reg = 1;
}
void sim_exit_irq_handler(void)
{
+ /* If any others are waiting, give the signal */
if (--handlers_pending > 0)
SDL_CondSignal(sim_thread_cond);