forked from len0rd/rockbox
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
This commit is contained in:
parent
e5d72ac5f7
commit
a9e69d935c
8 changed files with 37 additions and 126 deletions
|
@ -207,6 +207,18 @@ int tick_add_task(void (*f)(void));
|
||||||
int tick_remove_task(void (*f)(void));
|
int tick_remove_task(void (*f)(void));
|
||||||
extern void tick_start(unsigned int interval_in_ms);
|
extern void tick_start(unsigned int interval_in_ms);
|
||||||
|
|
||||||
|
/* inline helper for implementing target interrupt handler */
|
||||||
|
static inline void call_tick_tasks(void)
|
||||||
|
{
|
||||||
|
extern void (*tick_funcs[MAX_NUM_TICK_TASKS+1])(void);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
current_tick++;
|
||||||
|
|
||||||
|
for (i = 0; tick_funcs[i] != NULL; i++)
|
||||||
|
tick_funcs[i]();
|
||||||
|
}
|
||||||
|
|
||||||
struct timeout;
|
struct timeout;
|
||||||
|
|
||||||
/* timeout callback type
|
/* timeout callback type
|
||||||
|
|
|
@ -54,7 +54,9 @@
|
||||||
volatile long current_tick SHAREDDATA_ATTR = 0;
|
volatile long current_tick SHAREDDATA_ATTR = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
|
/* List of tick tasks - final element always NULL for termination */
|
||||||
|
void (*tick_funcs[MAX_NUM_TICK_TASKS+1])(void);
|
||||||
|
static int num_tick_funcs = 0;
|
||||||
|
|
||||||
extern struct core_entry cores[NUM_CORES];
|
extern struct core_entry cores[NUM_CORES];
|
||||||
|
|
||||||
|
@ -128,18 +130,8 @@ void tick_start(unsigned int interval_in_ms)
|
||||||
void IMIA0(void) __attribute__ ((interrupt_handler));
|
void IMIA0(void) __attribute__ ((interrupt_handler));
|
||||||
void IMIA0(void)
|
void IMIA0(void)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Run through the list of tick tasks */
|
/* Run through the list of tick tasks */
|
||||||
for(i = 0;i < MAX_NUM_TICK_TASKS;i++)
|
call_tick_tasks();
|
||||||
{
|
|
||||||
if(tick_funcs[i])
|
|
||||||
{
|
|
||||||
tick_funcs[i]();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
current_tick++;
|
|
||||||
|
|
||||||
TSR0 &= ~0x01;
|
TSR0 &= ~0x01;
|
||||||
}
|
}
|
||||||
|
@ -178,18 +170,8 @@ void tick_start(unsigned int interval_in_ms)
|
||||||
void TIMER0(void) __attribute__ ((interrupt_handler));
|
void TIMER0(void) __attribute__ ((interrupt_handler));
|
||||||
void TIMER0(void)
|
void TIMER0(void)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Run through the list of tick tasks */
|
/* Run through the list of tick tasks */
|
||||||
for(i = 0;i < MAX_NUM_TICK_TASKS;i++)
|
call_tick_tasks();
|
||||||
{
|
|
||||||
if(tick_funcs[i])
|
|
||||||
{
|
|
||||||
tick_funcs[i]();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
current_tick++;
|
|
||||||
|
|
||||||
TER0 = 0xff; /* Clear all events */
|
TER0 = 0xff; /* Clear all events */
|
||||||
}
|
}
|
||||||
|
@ -199,27 +181,17 @@ void TIMER0(void)
|
||||||
#ifndef BOOTLOADER
|
#ifndef BOOTLOADER
|
||||||
void TIMER1(void)
|
void TIMER1(void)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Run through the list of tick tasks (using main core) */
|
/* Run through the list of tick tasks (using main core) */
|
||||||
TIMER1_VAL; /* Read value to ack IRQ */
|
TIMER1_VAL; /* Read value to ack IRQ */
|
||||||
|
|
||||||
/* Run through the list of tick tasks using main CPU core -
|
/* Run through the list of tick tasks using main CPU core -
|
||||||
wake up the COP through its control interface to provide pulse */
|
wake up the COP through its control interface to provide pulse */
|
||||||
for (i = 0;i < MAX_NUM_TICK_TASKS;i++)
|
call_tick_tasks();
|
||||||
{
|
|
||||||
if (tick_funcs[i])
|
|
||||||
{
|
|
||||||
tick_funcs[i]();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if NUM_CORES > 1
|
#if NUM_CORES > 1
|
||||||
/* Pulse the COP */
|
/* Pulse the COP */
|
||||||
core_wake(COP);
|
core_wake(COP);
|
||||||
#endif /* NUM_CORES */
|
#endif /* NUM_CORES */
|
||||||
|
|
||||||
current_tick++;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -243,16 +215,8 @@ void tick_start(unsigned int interval_in_ms)
|
||||||
|
|
||||||
void timer_handler(void)
|
void timer_handler(void)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Run through the list of tick tasks */
|
/* Run through the list of tick tasks */
|
||||||
for(i = 0;i < MAX_NUM_TICK_TASKS;i++)
|
call_tick_tasks();
|
||||||
{
|
|
||||||
if(tick_funcs[i])
|
|
||||||
tick_funcs[i]();
|
|
||||||
}
|
|
||||||
|
|
||||||
current_tick++;
|
|
||||||
|
|
||||||
TIMER0.clr = 0;
|
TIMER0.clr = 0;
|
||||||
}
|
}
|
||||||
|
@ -274,19 +238,16 @@ void tick_start(unsigned int interval_in_ms)
|
||||||
|
|
||||||
int tick_add_task(void (*f)(void))
|
int tick_add_task(void (*f)(void))
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
int oldlevel = disable_irq_save();
|
int oldlevel = disable_irq_save();
|
||||||
|
|
||||||
/* Add a task if there is room */
|
/* Add a task if there is room */
|
||||||
for(i = 0;i < MAX_NUM_TICK_TASKS;i++)
|
if(num_tick_funcs < MAX_NUM_TICK_TASKS)
|
||||||
{
|
{
|
||||||
if(tick_funcs[i] == NULL)
|
tick_funcs[num_tick_funcs++] = f;
|
||||||
{
|
restore_irq(oldlevel);
|
||||||
tick_funcs[i] = f;
|
return 0;
|
||||||
restore_irq(oldlevel);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
restore_irq(oldlevel);
|
restore_irq(oldlevel);
|
||||||
panicf("Error! tick_add_task(): out of tasks");
|
panicf("Error! tick_add_task(): out of tasks");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -298,11 +259,16 @@ int tick_remove_task(void (*f)(void))
|
||||||
int oldlevel = disable_irq_save();
|
int oldlevel = disable_irq_save();
|
||||||
|
|
||||||
/* Remove a task if it is there */
|
/* Remove a task if it is there */
|
||||||
for(i = 0;i < MAX_NUM_TICK_TASKS;i++)
|
for(i = 0;i < num_tick_funcs;i++)
|
||||||
{
|
{
|
||||||
if(tick_funcs[i] == f)
|
if(tick_funcs[i] == f)
|
||||||
{
|
{
|
||||||
tick_funcs[i] = NULL;
|
/* Compact function list - propagates NULL-terminator as well */
|
||||||
|
for(; i < num_tick_funcs; i++)
|
||||||
|
tick_funcs[i] = tick_funcs[i+1];
|
||||||
|
|
||||||
|
num_tick_funcs--;
|
||||||
|
|
||||||
restore_irq(oldlevel);
|
restore_irq(oldlevel);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,22 +27,12 @@
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
|
|
||||||
|
|
||||||
static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void)
|
static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
EPITSR1 = EPITSR_OCIF; /* Clear the pending status */
|
EPITSR1 = EPITSR_OCIF; /* Clear the pending status */
|
||||||
|
|
||||||
/* Run through the list of tick tasks */
|
/* Run through the list of tick tasks */
|
||||||
for(i = 0;i < MAX_NUM_TICK_TASKS;i++)
|
call_tick_tasks();
|
||||||
{
|
|
||||||
if(tick_funcs[i])
|
|
||||||
tick_funcs[i]();
|
|
||||||
}
|
|
||||||
|
|
||||||
current_tick++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tick_start(unsigned int interval_in_ms)
|
void tick_start(unsigned int interval_in_ms)
|
||||||
|
|
|
@ -24,8 +24,6 @@
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
|
|
||||||
|
|
||||||
void tick_start(unsigned int interval_in_ms)
|
void tick_start(unsigned int interval_in_ms)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -62,18 +60,8 @@ void tick_start(unsigned int interval_in_ms)
|
||||||
|
|
||||||
void TIMER4(void)
|
void TIMER4(void)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Run through the list of tick tasks */
|
/* Run through the list of tick tasks */
|
||||||
for(i = 0; i < MAX_NUM_TICK_TASKS; i++)
|
call_tick_tasks();
|
||||||
{
|
|
||||||
if(tick_funcs[i])
|
|
||||||
{
|
|
||||||
tick_funcs[i]();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
current_tick++;
|
|
||||||
|
|
||||||
SRCPND = TIMER4_MASK;
|
SRCPND = TIMER4_MASK;
|
||||||
INTPND = TIMER4_MASK;
|
INTPND = TIMER4_MASK;
|
||||||
|
|
|
@ -51,24 +51,12 @@ void __timer_unregister(void)
|
||||||
|
|
||||||
|
|
||||||
/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */
|
/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */
|
||||||
|
|
||||||
extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
|
|
||||||
|
|
||||||
void TIMER(void)
|
void TIMER(void)
|
||||||
{
|
{
|
||||||
if (TIREQ & TF0) /* Timer0 reached ref value */
|
if (TIREQ & TF0) /* Timer0 reached ref value */
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Run through the list of tick tasks */
|
/* Run through the list of tick tasks */
|
||||||
for(i = 0; i < MAX_NUM_TICK_TASKS; i++)
|
call_tick_tasks();
|
||||||
{
|
|
||||||
if(tick_funcs[i])
|
|
||||||
{
|
|
||||||
tick_funcs[i]();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
current_tick++;
|
|
||||||
|
|
||||||
/* reset Timer 0 IRQ & ref flags */
|
/* reset Timer 0 IRQ & ref flags */
|
||||||
TIREQ |= TI0 | TF0;
|
TIREQ |= TI0 | TF0;
|
||||||
|
|
|
@ -46,25 +46,12 @@ void __timer_unregister(void)
|
||||||
|
|
||||||
|
|
||||||
/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */
|
/* Timer interrupt processing - all timers (inc. tick) have a single IRQ */
|
||||||
|
|
||||||
extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
|
|
||||||
|
|
||||||
void TIMER0(void)
|
void TIMER0(void)
|
||||||
{
|
{
|
||||||
if (TIREQ & TF0) /* Timer0 reached ref value */
|
if (TIREQ & TF0) /* Timer0 reached ref value */
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Run through the list of tick tasks */
|
/* Run through the list of tick tasks */
|
||||||
for(i = 0; i < MAX_NUM_TICK_TASKS; i++)
|
call_tick_tasks();
|
||||||
{
|
|
||||||
if(tick_funcs[i])
|
|
||||||
{
|
|
||||||
tick_funcs[i]();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
current_tick++;
|
|
||||||
|
|
||||||
/* reset Timer 0 IRQ & ref flags */
|
/* reset Timer 0 IRQ & ref flags */
|
||||||
TIREQ |= TI0 | TF0;
|
TIREQ |= TI0 | TF0;
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
|
|
||||||
|
|
||||||
void tick_start(unsigned int interval_in_ms)
|
void tick_start(unsigned int interval_in_ms)
|
||||||
{
|
{
|
||||||
/* TODO: set up TIMER1 clock settings
|
/* TODO: set up TIMER1 clock settings
|
||||||
|
@ -53,16 +51,7 @@ void tick_start(unsigned int interval_in_ms)
|
||||||
void TIMER1(void)
|
void TIMER1(void)
|
||||||
{
|
{
|
||||||
IO_INTC_IRQ0 = INTR_IRQ0_TMR1;
|
IO_INTC_IRQ0 = INTR_IRQ0_TMR1;
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Run through the list of tick tasks */
|
/* Run through the list of tick tasks */
|
||||||
for(i = 0; i < MAX_NUM_TICK_TASKS; i++)
|
call_tick_tasks();
|
||||||
{
|
|
||||||
if(tick_funcs[i])
|
|
||||||
{
|
|
||||||
tick_funcs[i]();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
current_tick++;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,6 @@
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "jz4740.h"
|
#include "jz4740.h"
|
||||||
|
|
||||||
extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
|
|
||||||
|
|
||||||
#define USE_RTC_CLOCK 0
|
#define USE_RTC_CLOCK 0
|
||||||
void tick_start(unsigned int interval_in_ms)
|
void tick_start(unsigned int interval_in_ms)
|
||||||
{
|
{
|
||||||
|
@ -70,13 +68,6 @@ void TCU0(void)
|
||||||
{
|
{
|
||||||
__tcu_clear_full_match_flag(0);
|
__tcu_clear_full_match_flag(0);
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Run through the list of tick tasks */
|
/* Run through the list of tick tasks */
|
||||||
for(i = 0; i < MAX_NUM_TICK_TASKS; i++)
|
call_tick_tasks();
|
||||||
{
|
|
||||||
if(tick_funcs[i])
|
|
||||||
tick_funcs[i]();
|
|
||||||
}
|
|
||||||
current_tick++;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue