diff options
Diffstat (limited to 'firmware/target/hosted/sdl/kernel-sdl.c')
-rw-r--r-- | firmware/target/hosted/sdl/kernel-sdl.c | 62 |
1 files changed, 58 insertions, 4 deletions
diff --git a/firmware/target/hosted/sdl/kernel-sdl.c b/firmware/target/hosted/sdl/kernel-sdl.c index d933b9097e..4fb1aede0a 100644 --- a/firmware/target/hosted/sdl/kernel-sdl.c +++ b/firmware/target/hosted/sdl/kernel-sdl.c | |||
@@ -34,6 +34,14 @@ | |||
34 | static SDL_TimerID tick_timer_id; | 34 | static SDL_TimerID tick_timer_id; |
35 | long start_tick; | 35 | long start_tick; |
36 | 36 | ||
37 | #ifndef HAVE_SDL_THREADS | ||
38 | /* for the wait_for_interrupt function */ | ||
39 | static bool do_exit; | ||
40 | static SDL_cond *wfi_cond; | ||
41 | static SDL_mutex *wfi_mutex; | ||
42 | #else | ||
43 | #define do_exit false | ||
44 | #endif | ||
37 | /* Condition to signal that "interrupts" may proceed */ | 45 | /* Condition to signal that "interrupts" may proceed */ |
38 | static SDL_cond *sim_thread_cond; | 46 | static SDL_cond *sim_thread_cond; |
39 | /* Mutex to serialize changing levels and exclude other threads while | 47 | /* Mutex to serialize changing levels and exclude other threads while |
@@ -98,6 +106,9 @@ void sim_exit_irq_handler(void) | |||
98 | 106 | ||
99 | status_reg = 0; | 107 | status_reg = 0; |
100 | SDL_UnlockMutex(sim_irq_mtx); | 108 | SDL_UnlockMutex(sim_irq_mtx); |
109 | #ifndef HAVE_SDL_THREADS | ||
110 | SDL_CondSignal(wfi_cond); | ||
111 | #endif | ||
101 | } | 112 | } |
102 | 113 | ||
103 | static bool sim_kernel_init(void) | 114 | static bool sim_kernel_init(void) |
@@ -115,15 +126,33 @@ static bool sim_kernel_init(void) | |||
115 | panicf("Cannot create sim_thread_cond\n"); | 126 | panicf("Cannot create sim_thread_cond\n"); |
116 | return false; | 127 | return false; |
117 | } | 128 | } |
118 | 129 | #ifndef HAVE_SDL_THREADS | |
130 | wfi_cond = SDL_CreateCond(); | ||
131 | if (wfi_cond == NULL) | ||
132 | { | ||
133 | panicf("Cannot create wfi\n"); | ||
134 | return false; | ||
135 | } | ||
136 | wfi_mutex = SDL_CreateMutex(); | ||
137 | if (wfi_mutex == NULL) | ||
138 | { | ||
139 | panicf("Cannot create wfi mutex\n"); | ||
140 | return false; | ||
141 | } | ||
142 | #endif | ||
119 | return true; | 143 | return true; |
120 | } | 144 | } |
121 | 145 | ||
122 | void sim_kernel_shutdown(void) | 146 | void sim_kernel_shutdown(void) |
123 | { | 147 | { |
124 | SDL_RemoveTimer(tick_timer_id); | 148 | SDL_RemoveTimer(tick_timer_id); |
149 | #ifndef HAVE_SDL_THREADS | ||
150 | do_exit = true; | ||
151 | SDL_CondSignal(wfi_cond); | ||
152 | #endif | ||
153 | disable_irq(); | ||
125 | SDL_DestroyMutex(sim_irq_mtx); | 154 | SDL_DestroyMutex(sim_irq_mtx); |
126 | SDL_DestroyCond(sim_thread_cond); | 155 | SDL_DestroyCond(sim_thread_cond); |
127 | } | 156 | } |
128 | 157 | ||
129 | Uint32 tick_timer(Uint32 interval, void *param) | 158 | Uint32 tick_timer(Uint32 interval, void *param) |
@@ -135,7 +164,7 @@ Uint32 tick_timer(Uint32 interval, void *param) | |||
135 | 164 | ||
136 | new_tick = (SDL_GetTicks() - start_tick) / (1000/HZ); | 165 | new_tick = (SDL_GetTicks() - start_tick) / (1000/HZ); |
137 | 166 | ||
138 | while(new_tick != current_tick) | 167 | while(new_tick != current_tick && !do_exit) |
139 | { | 168 | { |
140 | sim_enter_irq_handler(); | 169 | sim_enter_irq_handler(); |
141 | 170 | ||
@@ -146,7 +175,7 @@ Uint32 tick_timer(Uint32 interval, void *param) | |||
146 | sim_exit_irq_handler(); | 175 | sim_exit_irq_handler(); |
147 | } | 176 | } |
148 | 177 | ||
149 | return interval; | 178 | return do_exit ? 0 : interval; |
150 | } | 179 | } |
151 | 180 | ||
152 | void tick_start(unsigned int interval_in_ms) | 181 | void tick_start(unsigned int interval_in_ms) |
@@ -168,4 +197,29 @@ void tick_start(unsigned int interval_in_ms) | |||
168 | } | 197 | } |
169 | 198 | ||
170 | tick_timer_id = SDL_AddTimer(interval_in_ms, tick_timer, NULL); | 199 | tick_timer_id = SDL_AddTimer(interval_in_ms, tick_timer, NULL); |
200 | #ifndef HAVE_SDL_THREADS | ||
201 | SDL_LockMutex(wfi_mutex); | ||
202 | #endif | ||
203 | } | ||
204 | |||
205 | #ifndef HAVE_SDL_THREADS | ||
206 | static 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 | |||
217 | void wait_for_interrupt(void) | ||
218 | { | ||
219 | /* the exit may come at any time, during the CondWait or before, | ||
220 | * so check it twice */ | ||
221 | check_exit(); | ||
222 | SDL_CondWait(wfi_cond, wfi_mutex); | ||
223 | check_exit(); | ||
171 | } | 224 | } |
225 | #endif | ||