summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/target/hosted/maemo/maemo-thread.c10
-rw-r--r--firmware/target/hosted/sdl/button-sdl.c8
-rw-r--r--firmware/target/hosted/sdl/kernel-sdl.c32
-rw-r--r--firmware/target/hosted/sdl/system-sdl.c32
-rw-r--r--firmware/target/hosted/sdl/system-sdl.h4
5 files changed, 45 insertions, 41 deletions
diff --git a/firmware/target/hosted/maemo/maemo-thread.c b/firmware/target/hosted/maemo/maemo-thread.c
index 6593a9faa5..a0e5824252 100644
--- a/firmware/target/hosted/maemo/maemo-thread.c
+++ b/firmware/target/hosted/maemo/maemo-thread.c
@@ -23,7 +23,6 @@
23#include <libhal.h> 23#include <libhal.h>
24#include <libosso.h> 24#include <libosso.h>
25#include <SDL_thread.h> 25#include <SDL_thread.h>
26#include <SDL_events.h>
27 26
28#include "config.h" 27#include "config.h"
29#include "system.h" 28#include "system.h"
@@ -212,15 +211,6 @@ void reset_poweroff_timer(void)
212{ 211{
213} 212}
214 213
215void shutdown_hw(void)
216{
217 /* Shut down SDL event loop */
218 SDL_Event event;
219 memset(&event, 0, sizeof(SDL_Event));
220 event.type = SDL_USEREVENT;
221 SDL_PushEvent(&event);
222}
223
224void cancel_shutdown(void) 214void cancel_shutdown(void)
225{ 215{
226} 216}
diff --git a/firmware/target/hosted/sdl/button-sdl.c b/firmware/target/hosted/sdl/button-sdl.c
index 00afc0c8ef..f14e53fb44 100644
--- a/firmware/target/hosted/sdl/button-sdl.c
+++ b/firmware/target/hosted/sdl/button-sdl.c
@@ -275,8 +275,8 @@ static bool event_handler(SDL_Event *event)
275 break; 275 break;
276 } 276 }
277 case SDL_QUIT: 277 case SDL_QUIT:
278 /* Post SYS_POWEROFF event. Will post SDL_USEREVENT in shutdown_hw() if successful. */ 278 /* Will post SDL_USEREVENT in shutdown_hw() if successful. */
279 queue_broadcast(SYS_POWEROFF, 0); 279 sys_poweroff();
280 break; 280 break;
281 case SDL_USEREVENT: 281 case SDL_USEREVENT:
282 return true; 282 return true;
@@ -324,8 +324,8 @@ static void button_event(int key, bool pressed)
324 324
325#if (CONFIG_PLATFORM & PLATFORM_PANDORA) 325#if (CONFIG_PLATFORM & PLATFORM_PANDORA)
326 case SDLK_LCTRL: 326 case SDLK_LCTRL:
327 /* Post SYS_POWEROFF event. Will post SDL_USEREVENT in shutdown_hw() if successful. */ 327 /* Will post SDL_USEREVENT in shutdown_hw() if successful. */
328 queue_broadcast(SYS_POWEROFF, 0); 328 sys_poweroff();
329 break; 329 break;
330#endif 330#endif
331#ifdef HAS_BUTTON_HOLD 331#ifdef HAS_BUTTON_HOLD
diff --git a/firmware/target/hosted/sdl/kernel-sdl.c b/firmware/target/hosted/sdl/kernel-sdl.c
index 4fb1aede0a..5c16f86749 100644
--- a/firmware/target/hosted/sdl/kernel-sdl.c
+++ b/firmware/target/hosted/sdl/kernel-sdl.c
@@ -36,11 +36,8 @@ long start_tick;
36 36
37#ifndef HAVE_SDL_THREADS 37#ifndef HAVE_SDL_THREADS
38/* for the wait_for_interrupt function */ 38/* for the wait_for_interrupt function */
39static bool do_exit;
40static SDL_cond *wfi_cond; 39static SDL_cond *wfi_cond;
41static SDL_mutex *wfi_mutex; 40static SDL_mutex *wfi_mutex;
42#else
43#define do_exit false
44#endif 41#endif
45/* Condition to signal that "interrupts" may proceed */ 42/* Condition to signal that "interrupts" may proceed */
46static SDL_cond *sim_thread_cond; 43static SDL_cond *sim_thread_cond;
@@ -74,7 +71,7 @@ int set_irq_level(int level)
74 /* Not in a handler and "interrupts" are going from disabled to 71 /* Not in a handler and "interrupts" are going from disabled to
75 * enabled; signal any pending handlers still waiting */ 72 * enabled; signal any pending handlers still waiting */
76 if (handlers_pending > 0) 73 if (handlers_pending > 0)
77 SDL_CondSignal(sim_thread_cond); 74 SDL_CondBroadcast(sim_thread_cond);
78 } 75 }
79 76
80 interrupt_level = level; /* save new level */ 77 interrupt_level = level; /* save new level */
@@ -147,10 +144,14 @@ void sim_kernel_shutdown(void)
147{ 144{
148 SDL_RemoveTimer(tick_timer_id); 145 SDL_RemoveTimer(tick_timer_id);
149#ifndef HAVE_SDL_THREADS 146#ifndef HAVE_SDL_THREADS
150 do_exit = true; 147 SDL_DestroyCond(wfi_cond);
151 SDL_CondSignal(wfi_cond); 148 SDL_UnlockMutex(wfi_mutex);
149 SDL_DestroyMutex(wfi_mutex);
152#endif 150#endif
153 disable_irq(); 151 enable_irq();
152 while(handlers_pending > 0)
153 SDL_Delay(10);
154
154 SDL_DestroyMutex(sim_irq_mtx); 155 SDL_DestroyMutex(sim_irq_mtx);
155 SDL_DestroyCond(sim_thread_cond); 156 SDL_DestroyCond(sim_thread_cond);
156} 157}
@@ -164,7 +165,7 @@ Uint32 tick_timer(Uint32 interval, void *param)
164 165
165 new_tick = (SDL_GetTicks() - start_tick) / (1000/HZ); 166 new_tick = (SDL_GetTicks() - start_tick) / (1000/HZ);
166 167
167 while(new_tick != current_tick && !do_exit) 168 while(new_tick != current_tick)
168 { 169 {
169 sim_enter_irq_handler(); 170 sim_enter_irq_handler();
170 171
@@ -175,7 +176,7 @@ Uint32 tick_timer(Uint32 interval, void *param)
175 sim_exit_irq_handler(); 176 sim_exit_irq_handler();
176 } 177 }
177 178
178 return do_exit ? 0 : interval; 179 return interval;
179} 180}
180 181
181void tick_start(unsigned int interval_in_ms) 182void tick_start(unsigned int interval_in_ms)
@@ -203,23 +204,10 @@ void tick_start(unsigned int interval_in_ms)
203} 204}
204 205
205#ifndef HAVE_SDL_THREADS 206#ifndef HAVE_SDL_THREADS
206static void check_exit(void)
207{
208 if (UNLIKELY(do_exit))
209 {
210 SDL_DestroyCond(wfi_cond);
211 SDL_UnlockMutex(wfi_mutex);
212 SDL_DestroyMutex(wfi_mutex);
213 sim_do_exit();
214 }
215}
216
217void wait_for_interrupt(void) 207void wait_for_interrupt(void)
218{ 208{
219 /* the exit may come at any time, during the CondWait or before, 209 /* the exit may come at any time, during the CondWait or before,
220 * so check it twice */ 210 * so check it twice */
221 check_exit();
222 SDL_CondWait(wfi_cond, wfi_mutex); 211 SDL_CondWait(wfi_cond, wfi_mutex);
223 check_exit();
224} 212}
225#endif 213#endif
diff --git a/firmware/target/hosted/sdl/system-sdl.c b/firmware/target/hosted/sdl/system-sdl.c
index 4dc5509397..7ddc5f8699 100644
--- a/firmware/target/hosted/sdl/system-sdl.c
+++ b/firmware/target/hosted/sdl/system-sdl.c
@@ -71,9 +71,10 @@ bool debug_audio = false;
71bool debug_wps = false; 71bool debug_wps = false;
72int wps_verbose_level = 3; 72int wps_verbose_level = 3;
73 73
74
75void sys_poweroff(void) 74void sys_poweroff(void)
76{ 75{
76 /* Post SYS_POWEROFF event. Will post SDL_USEREVENT in shutdown_hw() if successful. */
77 queue_broadcast(SYS_POWEROFF, 0);
77} 78}
78 79
79/* 80/*
@@ -187,16 +188,39 @@ static int sdl_event_thread(void * param)
187#ifdef HAVE_SDL_THREADS 188#ifdef HAVE_SDL_THREADS
188 sim_thread_shutdown(); /* not needed for native threads */ 189 sim_thread_shutdown(); /* not needed for native threads */
189#endif 190#endif
190 sim_kernel_shutdown();
191
192 return 0; 191 return 0;
193} 192}
194 193
195void sim_do_exit(void) 194void shutdown_hw(void)
196{ 195{
196 /* Shut down SDL event loop */
197 SDL_Event event;
198 memset(&event, 0, sizeof(SDL_Event));
199 event.type = SDL_USEREVENT;
200 SDL_PushEvent(&event);
201#ifdef HAVE_SDL_THREADS
202 /* since sim_thread_shutdown() grabs the mutex we need to let it free,
203 * otherwise SDL_WaitThread will deadlock */
204 struct thread_entry* t = sim_thread_unlock();
205#endif
197 /* wait for event thread to finish */ 206 /* wait for event thread to finish */
198 SDL_WaitThread(evt_thread, NULL); 207 SDL_WaitThread(evt_thread, NULL);
199 208
209#ifdef HAVE_SDL_THREADS
210 /* lock again before entering the scheduler */
211 sim_thread_lock(t);
212 /* sim_thread_shutdown() will cause sim_do_exit() to be called via longjmp,
213 * but only if we let the sdl thread scheduler exit the other threads */
214 while(1) yield();
215#else
216 sim_do_exit();
217#endif
218}
219
220void sim_do_exit()
221{
222 sim_kernel_shutdown();
223
200 SDL_Quit(); 224 SDL_Quit();
201 exit(EXIT_SUCCESS); 225 exit(EXIT_SUCCESS);
202} 226}
diff --git a/firmware/target/hosted/sdl/system-sdl.h b/firmware/target/hosted/sdl/system-sdl.h
index bec01ec81d..9021a12543 100644
--- a/firmware/target/hosted/sdl/system-sdl.h
+++ b/firmware/target/hosted/sdl/system-sdl.h
@@ -22,6 +22,8 @@
22#define _SYSTEM_SDL_H_ 22#define _SYSTEM_SDL_H_
23 23
24#include <stdbool.h> 24#include <stdbool.h>
25#include "config.h"
26#include "gcc_extensions.h"
25 27
26#define HIGHEST_IRQ_LEVEL 1 28#define HIGHEST_IRQ_LEVEL 1
27 29
@@ -45,7 +47,7 @@ void sim_kernel_shutdown(void);
45void sys_poweroff(void); 47void sys_poweroff(void);
46void sys_handle_argv(int argc, char *argv[]); 48void sys_handle_argv(int argc, char *argv[]);
47void gui_message_loop(void); 49void gui_message_loop(void);
48void sim_do_exit(void); 50void sim_do_exit(void) NORETURN_ATTR;
49#ifndef HAVE_SDL_THREADS 51#ifndef HAVE_SDL_THREADS
50void wait_for_interrupt(void); 52void wait_for_interrupt(void);
51#endif 53#endif