summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2008-10-27 16:30:24 +0000
committerMichael Sevakis <jethead71@rockbox.org>2008-10-27 16:30:24 +0000
commita9e69d935cb5c2e5ffca1bbc977252ce7661d343 (patch)
tree8ac65804b294cfe7cc55febe445f904a1b33cb0e
parente5d72ac5f767a66b11c7a46dfb4edd322f7a723d (diff)
downloadrockbox-a9e69d935cb5c2e5ffca1bbc977252ce7661d343.tar.gz
rockbox-a9e69d935cb5c2e5ffca1bbc977252ce7661d343.zip
Strange little kernel optimization to ease targeting the timer tick and to limit the number of loops in the tick function to the number of tasks added rather than always looping the max number.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18893 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/export/kernel.h12
-rw-r--r--firmware/kernel.c72
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c12
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c14
-rw-r--r--firmware/target/arm/tcc77x/timer-tcc77x.c14
-rw-r--r--firmware/target/arm/tcc780x/timer-tcc780x.c15
-rw-r--r--firmware/target/arm/tms320dm320/kernel-dm320.c13
-rw-r--r--firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c11
8 files changed, 37 insertions, 126 deletions
diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h
index 51eb635004..9438f6d308 100644
--- a/firmware/export/kernel.h
+++ b/firmware/export/kernel.h
@@ -207,6 +207,18 @@ int tick_add_task(void (*f)(void));
207int tick_remove_task(void (*f)(void)); 207int tick_remove_task(void (*f)(void));
208extern void tick_start(unsigned int interval_in_ms); 208extern void tick_start(unsigned int interval_in_ms);
209 209
210/* inline helper for implementing target interrupt handler */
211static inline void call_tick_tasks(void)
212{
213 extern void (*tick_funcs[MAX_NUM_TICK_TASKS+1])(void);
214 int i;
215
216 current_tick++;
217
218 for (i = 0; tick_funcs[i] != NULL; i++)
219 tick_funcs[i]();
220}
221
210struct timeout; 222struct timeout;
211 223
212/* timeout callback type 224/* timeout callback type
diff --git a/firmware/kernel.c b/firmware/kernel.c
index fb9c5e2449..70b3e03615 100644
--- a/firmware/kernel.c
+++ b/firmware/kernel.c
@@ -54,7 +54,9 @@
54volatile long current_tick SHAREDDATA_ATTR = 0; 54volatile long current_tick SHAREDDATA_ATTR = 0;
55#endif 55#endif
56 56
57void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); 57/* List of tick tasks - final element always NULL for termination */
58void (*tick_funcs[MAX_NUM_TICK_TASKS+1])(void);
59static int num_tick_funcs = 0;
58 60
59extern struct core_entry cores[NUM_CORES]; 61extern struct core_entry cores[NUM_CORES];
60 62
@@ -128,18 +130,8 @@ void tick_start(unsigned int interval_in_ms)
128void IMIA0(void) __attribute__ ((interrupt_handler)); 130void IMIA0(void) __attribute__ ((interrupt_handler));
129void IMIA0(void) 131void IMIA0(void)
130{ 132{
131 int i;
132
133 /* Run through the list of tick tasks */ 133 /* Run through the list of tick tasks */
134 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 134 call_tick_tasks();
135 {
136 if(tick_funcs[i])
137 {
138 tick_funcs[i]();
139 }
140 }
141
142 current_tick++;
143 135
144 TSR0 &= ~0x01; 136 TSR0 &= ~0x01;
145} 137}
@@ -178,18 +170,8 @@ void tick_start(unsigned int interval_in_ms)
178void TIMER0(void) __attribute__ ((interrupt_handler)); 170void TIMER0(void) __attribute__ ((interrupt_handler));
179void TIMER0(void) 171void TIMER0(void)
180{ 172{
181 int i;
182
183 /* Run through the list of tick tasks */ 173 /* Run through the list of tick tasks */
184 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 174 call_tick_tasks();
185 {
186 if(tick_funcs[i])
187 {
188 tick_funcs[i]();
189 }
190 }
191
192 current_tick++;
193 175
194 TER0 = 0xff; /* Clear all events */ 176 TER0 = 0xff; /* Clear all events */
195} 177}
@@ -199,27 +181,17 @@ void TIMER0(void)
199#ifndef BOOTLOADER 181#ifndef BOOTLOADER
200void TIMER1(void) 182void TIMER1(void)
201{ 183{
202 int i;
203
204 /* Run through the list of tick tasks (using main core) */ 184 /* Run through the list of tick tasks (using main core) */
205 TIMER1_VAL; /* Read value to ack IRQ */ 185 TIMER1_VAL; /* Read value to ack IRQ */
206 186
207 /* Run through the list of tick tasks using main CPU core - 187 /* Run through the list of tick tasks using main CPU core -
208 wake up the COP through its control interface to provide pulse */ 188 wake up the COP through its control interface to provide pulse */
209 for (i = 0;i < MAX_NUM_TICK_TASKS;i++) 189 call_tick_tasks();
210 {
211 if (tick_funcs[i])
212 {
213 tick_funcs[i]();
214 }
215 }
216 190
217#if NUM_CORES > 1 191#if NUM_CORES > 1
218 /* Pulse the COP */ 192 /* Pulse the COP */
219 core_wake(COP); 193 core_wake(COP);
220#endif /* NUM_CORES */ 194#endif /* NUM_CORES */
221
222 current_tick++;
223} 195}
224#endif 196#endif
225 197
@@ -243,16 +215,8 @@ void tick_start(unsigned int interval_in_ms)
243 215
244void timer_handler(void) 216void timer_handler(void)
245{ 217{
246 int i;
247
248 /* Run through the list of tick tasks */ 218 /* Run through the list of tick tasks */
249 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 219 call_tick_tasks();
250 {
251 if(tick_funcs[i])
252 tick_funcs[i]();
253 }
254
255 current_tick++;
256 220
257 TIMER0.clr = 0; 221 TIMER0.clr = 0;
258} 222}
@@ -274,19 +238,16 @@ void tick_start(unsigned int interval_in_ms)
274 238
275int tick_add_task(void (*f)(void)) 239int tick_add_task(void (*f)(void))
276{ 240{
277 int i;
278 int oldlevel = disable_irq_save(); 241 int oldlevel = disable_irq_save();
279 242
280 /* Add a task if there is room */ 243 /* Add a task if there is room */
281 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 244 if(num_tick_funcs < MAX_NUM_TICK_TASKS)
282 { 245 {
283 if(tick_funcs[i] == NULL) 246 tick_funcs[num_tick_funcs++] = f;
284 { 247 restore_irq(oldlevel);
285 tick_funcs[i] = f; 248 return 0;
286 restore_irq(oldlevel);
287 return 0;
288 }
289 } 249 }
250
290 restore_irq(oldlevel); 251 restore_irq(oldlevel);
291 panicf("Error! tick_add_task(): out of tasks"); 252 panicf("Error! tick_add_task(): out of tasks");
292 return -1; 253 return -1;
@@ -298,11 +259,16 @@ int tick_remove_task(void (*f)(void))
298 int oldlevel = disable_irq_save(); 259 int oldlevel = disable_irq_save();
299 260
300 /* Remove a task if it is there */ 261 /* Remove a task if it is there */
301 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 262 for(i = 0;i < num_tick_funcs;i++)
302 { 263 {
303 if(tick_funcs[i] == f) 264 if(tick_funcs[i] == f)
304 { 265 {
305 tick_funcs[i] = NULL; 266 /* Compact function list - propagates NULL-terminator as well */
267 for(; i < num_tick_funcs; i++)
268 tick_funcs[i] = tick_funcs[i+1];
269
270 num_tick_funcs--;
271
306 restore_irq(oldlevel); 272 restore_irq(oldlevel);
307 return 0; 273 return 0;
308 } 274 }
diff --git a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c
index e7bce8dc2c..3d7c577e3c 100644
--- a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c
@@ -27,22 +27,12 @@
27#include "kernel.h" 27#include "kernel.h"
28#include "thread.h" 28#include "thread.h"
29 29
30extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
31
32static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void) 30static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void)
33{ 31{
34 int i;
35
36 EPITSR1 = EPITSR_OCIF; /* Clear the pending status */ 32 EPITSR1 = EPITSR_OCIF; /* Clear the pending status */
37 33
38 /* Run through the list of tick tasks */ 34 /* Run through the list of tick tasks */
39 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 35 call_tick_tasks();
40 {
41 if(tick_funcs[i])
42 tick_funcs[i]();
43 }
44
45 current_tick++;
46} 36}
47 37
48void tick_start(unsigned int interval_in_ms) 38void tick_start(unsigned int interval_in_ms)
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c
index 4f878d4ed3..76917c8c82 100644
--- a/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c
+++ b/firmware/target/arm/s3c2440/gigabeat-fx/kernel-meg-fx.c
@@ -24,8 +24,6 @@
24#include "timer.h" 24#include "timer.h"
25#include "thread.h" 25#include "thread.h"
26 26
27extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
28
29void tick_start(unsigned int interval_in_ms) 27void tick_start(unsigned int interval_in_ms)
30{ 28{
31 /* 29 /*
@@ -62,18 +60,8 @@ void tick_start(unsigned int interval_in_ms)
62 60
63void TIMER4(void) 61void TIMER4(void)
64{ 62{
65 int i;
66
67 /* Run through the list of tick tasks */ 63 /* Run through the list of tick tasks */
68 for(i = 0; i < MAX_NUM_TICK_TASKS; i++) 64 call_tick_tasks();
69 {
70 if(tick_funcs[i])
71 {
72 tick_funcs[i]();
73 }
74 }
75
76 current_tick++;
77 65
78 SRCPND = TIMER4_MASK; 66 SRCPND = TIMER4_MASK;
79 INTPND = TIMER4_MASK; 67 INTPND = TIMER4_MASK;
diff --git a/firmware/target/arm/tcc77x/timer-tcc77x.c b/firmware/target/arm/tcc77x/timer-tcc77x.c
index 4645e388cc..924ddda625 100644
--- a/firmware/target/arm/tcc77x/timer-tcc77x.c
+++ b/firmware/target/arm/tcc77x/timer-tcc77x.c
@@ -51,24 +51,12 @@ void __timer_unregister(void)
51 51
52 52
53/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */ 53/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */
54
55extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
56
57void TIMER(void) 54void TIMER(void)
58{ 55{
59 if (TIREQ & TF0) /* Timer0 reached ref value */ 56 if (TIREQ & TF0) /* Timer0 reached ref value */
60 { 57 {
61 int i;
62
63 /* Run through the list of tick tasks */ 58 /* Run through the list of tick tasks */
64 for(i = 0; i < MAX_NUM_TICK_TASKS; i++) 59 call_tick_tasks();
65 {
66 if(tick_funcs[i])
67 {
68 tick_funcs[i]();
69 }
70 }
71 current_tick++;
72 60
73 /* reset Timer 0 IRQ & ref flags */ 61 /* reset Timer 0 IRQ & ref flags */
74 TIREQ |= TI0 | TF0; 62 TIREQ |= TI0 | TF0;
diff --git a/firmware/target/arm/tcc780x/timer-tcc780x.c b/firmware/target/arm/tcc780x/timer-tcc780x.c
index c08520116a..17956131c0 100644
--- a/firmware/target/arm/tcc780x/timer-tcc780x.c
+++ b/firmware/target/arm/tcc780x/timer-tcc780x.c
@@ -46,25 +46,12 @@ void __timer_unregister(void)
46 46
47 47
48/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */ 48/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */
49
50extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
51
52void TIMER0(void) 49void TIMER0(void)
53{ 50{
54 if (TIREQ & TF0) /* Timer0 reached ref value */ 51 if (TIREQ & TF0) /* Timer0 reached ref value */
55 { 52 {
56 int i;
57
58 /* Run through the list of tick tasks */ 53 /* Run through the list of tick tasks */
59 for(i = 0; i < MAX_NUM_TICK_TASKS; i++) 54 call_tick_tasks();
60 {
61 if(tick_funcs[i])
62 {
63 tick_funcs[i]();
64 }
65 }
66
67 current_tick++;
68 55
69 /* reset Timer 0 IRQ & ref flags */ 56 /* reset Timer 0 IRQ & ref flags */
70 TIREQ |= TI0 | TF0; 57 TIREQ |= TI0 | TF0;
diff --git a/firmware/target/arm/tms320dm320/kernel-dm320.c b/firmware/target/arm/tms320dm320/kernel-dm320.c
index 42f9773d36..b5eb4233e4 100644
--- a/firmware/target/arm/tms320dm320/kernel-dm320.c
+++ b/firmware/target/arm/tms320dm320/kernel-dm320.c
@@ -25,8 +25,6 @@
25#include "timer.h" 25#include "timer.h"
26#include "thread.h" 26#include "thread.h"
27 27
28extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
29
30void tick_start(unsigned int interval_in_ms) 28void tick_start(unsigned int interval_in_ms)
31{ 29{
32/* TODO: set up TIMER1 clock settings 30/* TODO: set up TIMER1 clock settings
@@ -53,16 +51,7 @@ void tick_start(unsigned int interval_in_ms)
53void TIMER1(void) 51void TIMER1(void)
54{ 52{
55 IO_INTC_IRQ0 = INTR_IRQ0_TMR1; 53 IO_INTC_IRQ0 = INTR_IRQ0_TMR1;
56
57 int i;
58 54
59 /* Run through the list of tick tasks */ 55 /* Run through the list of tick tasks */
60 for(i = 0; i < MAX_NUM_TICK_TASKS; i++) 56 call_tick_tasks();
61 {
62 if(tick_funcs[i])
63 {
64 tick_funcs[i]();
65 }
66 }
67 current_tick++;
68} 57}
diff --git a/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c b/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
index 62176cee24..dcfdfd6a38 100644
--- a/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/kernel-jz4740.c
@@ -24,8 +24,6 @@
24#include "kernel.h" 24#include "kernel.h"
25#include "jz4740.h" 25#include "jz4740.h"
26 26
27extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
28
29#define USE_RTC_CLOCK 0 27#define USE_RTC_CLOCK 0
30void tick_start(unsigned int interval_in_ms) 28void tick_start(unsigned int interval_in_ms)
31{ 29{
@@ -70,13 +68,6 @@ void TCU0(void)
70{ 68{
71 __tcu_clear_full_match_flag(0); 69 __tcu_clear_full_match_flag(0);
72 70
73 int i;
74
75 /* Run through the list of tick tasks */ 71 /* Run through the list of tick tasks */
76 for(i = 0; i < MAX_NUM_TICK_TASKS; i++) 72 call_tick_tasks();
77 {
78 if(tick_funcs[i])
79 tick_funcs[i]();
80 }
81 current_tick++;
82} 73}