summaryrefslogtreecommitdiff
path: root/firmware/target/hosted/sdl/kernel-sdl.c
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-05-15 21:02:47 +0000
committerThomas Martitz <kugel@rockbox.org>2010-05-15 21:02:47 +0000
commit3d0cee8abbaf764958743e8a7851eee94e60a913 (patch)
treea96b1ec825003a71643a7da4707c300f64824f82 /firmware/target/hosted/sdl/kernel-sdl.c
parentdcf442e61f21fb2aef5ce7de0547f733557b156e (diff)
downloadrockbox-3d0cee8abbaf764958743e8a7851eee94e60a913.tar.gz
rockbox-3d0cee8abbaf764958743e8a7851eee94e60a913.zip
- Move uisimulator/sdl/*.[ch] into the target tree, under firmware/target/hosted/sdl, uisdl.c is split up across button-sdl.c and system-sdl.c.
- Refactor the program startup. main() is now in main.c like on target, and the implicit application thread will now act as our main thread (previously a separate one was created for this in thread initialization). This is part of Rockbox as an application and is the first step to make an application port from the uisimulator. In a further step the sim bits from the sdl build will be separated out. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26065 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/hosted/sdl/kernel-sdl.c')
-rw-r--r--firmware/target/hosted/sdl/kernel-sdl.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/firmware/target/hosted/sdl/kernel-sdl.c b/firmware/target/hosted/sdl/kernel-sdl.c
new file mode 100644
index 0000000000..d796921e35
--- /dev/null
+++ b/firmware/target/hosted/sdl/kernel-sdl.c
@@ -0,0 +1,162 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Felix Arends
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdlib.h>
23#include <stdio.h>
24#include <SDL.h>
25#include <SDL_thread.h>
26#include "memory.h"
27#include "system-sdl.h"
28#include "thread-sdl.h"
29#include "kernel.h"
30#include "thread.h"
31#include "panic.h"
32#include "debug.h"
33
34static SDL_TimerID tick_timer_id;
35long start_tick;
36
37/* Condition to signal that "interrupts" may proceed */
38static SDL_cond *sim_thread_cond;
39/* Mutex to serialize changing levels and exclude other threads while
40 * inside a handler */
41static SDL_mutex *sim_irq_mtx;
42static int interrupt_level = HIGHEST_IRQ_LEVEL;
43static int handlers_pending = 0;
44static int status_reg = 0;
45
46/* Nescessary logic:
47 * 1) All threads must pass unblocked
48 * 2) Current handler must always pass unblocked
49 * 3) Threads must be excluded when irq routine is running
50 * 4) No more than one handler routine should execute at a time
51 */
52int set_irq_level(int level)
53{
54 SDL_LockMutex(sim_irq_mtx);
55
56 int oldlevel = interrupt_level;
57
58 if (status_reg == 0 && level == 0 && oldlevel != 0)
59 {
60 /* Not in a handler and "interrupts" are being reenabled */
61 if (handlers_pending > 0)
62 SDL_CondSignal(sim_thread_cond);
63 }
64
65 interrupt_level = level; /* save new level */
66
67 SDL_UnlockMutex(sim_irq_mtx);
68 return oldlevel;
69}
70
71void sim_enter_irq_handler(void)
72{
73 SDL_LockMutex(sim_irq_mtx);
74 handlers_pending++;
75
76 if(interrupt_level != 0)
77 {
78 /* "Interrupts" are disabled. Wait for reenable */
79 SDL_CondWait(sim_thread_cond, sim_irq_mtx);
80 }
81
82 status_reg = 1;
83}
84
85void sim_exit_irq_handler(void)
86{
87 if (--handlers_pending > 0)
88 SDL_CondSignal(sim_thread_cond);
89
90 status_reg = 0;
91 SDL_UnlockMutex(sim_irq_mtx);
92}
93
94static bool sim_kernel_init(void)
95{
96 sim_irq_mtx = SDL_CreateMutex();
97 if (sim_irq_mtx == NULL)
98 {
99 panicf("Cannot create sim_handler_mtx\n");
100 return false;
101 }
102
103 sim_thread_cond = SDL_CreateCond();
104 if (sim_thread_cond == NULL)
105 {
106 panicf("Cannot create sim_thread_cond\n");
107 return false;
108 }
109
110 return true;
111}
112
113void sim_kernel_shutdown(void)
114{
115 SDL_RemoveTimer(tick_timer_id);
116 SDL_DestroyMutex(sim_irq_mtx);
117 SDL_DestroyCond(sim_thread_cond);
118}
119
120Uint32 tick_timer(Uint32 interval, void *param)
121{
122 long new_tick;
123
124 (void) interval;
125 (void) param;
126
127 new_tick = (SDL_GetTicks() - start_tick) / (1000/HZ);
128
129 while(new_tick != current_tick)
130 {
131 sim_enter_irq_handler();
132
133 /* Run through the list of tick tasks - increments tick
134 * on each iteration. */
135 call_tick_tasks();
136
137 sim_exit_irq_handler();
138 }
139
140 return 1;
141}
142
143void tick_start(unsigned int interval_in_ms)
144{
145 if (!sim_kernel_init())
146 {
147 panicf("Could not initialize kernel!");
148 exit(-1);
149 }
150
151 if (tick_timer_id != NULL)
152 {
153 SDL_RemoveTimer(tick_timer_id);
154 tick_timer_id = NULL;
155 }
156 else
157 {
158 start_tick = SDL_GetTicks();
159 }
160
161 tick_timer_id = SDL_AddTimer(interval_in_ms, tick_timer, NULL);
162}