mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-28 02:35:28 +00:00
Track current task directly instead of computing from stack pointer
This is a precursor to supporting task-specific task sizes. I've benchmarked this vs. the current stack pointer method; no measurable performance difference. BUG=chrome-os-partner:13814 TEST=boot EC; taskinfo; if it boots and doesn't print garbage, it worked BRANCH=all Change-Id: Ia326c3ab499ac03cce78dbacaa52f735601a171e Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/32603 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
@@ -19,8 +19,7 @@
|
||||
* Global memory size for a task : 512 bytes
|
||||
* including its contexts and its stack
|
||||
*/
|
||||
#define TASK_SIZE_LOG2 9
|
||||
#define TASK_SIZE (1<<TASK_SIZE_LOG2)
|
||||
#define TASK_SIZE 512
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
@@ -124,6 +123,8 @@ static task_ tasks[TASK_ID_COUNT] __attribute__((section(".bss.tasks")))
|
||||
* in its own section which immediately follows .bss.tasks in ec.lds.S. */
|
||||
uint32_t scratchpad[17] __attribute__((section(".bss.task_scratchpad")));
|
||||
|
||||
static task_ *current_task = (task_ *)scratchpad;
|
||||
|
||||
/* Should IRQs chain to svc_handler()? This should be set if either of the
|
||||
* following is true:
|
||||
*
|
||||
@@ -144,30 +145,6 @@ static uint32_t tasks_ready = (1<<TASK_ID_COUNT) - 1;
|
||||
|
||||
static int start_called; /* Has task swapping started */
|
||||
|
||||
|
||||
static task_ *__get_current(void)
|
||||
{
|
||||
unsigned sp;
|
||||
|
||||
asm("mov %0, sp":"=r"(sp));
|
||||
return (task_ *)((sp - 4) & ~(TASK_SIZE-1));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a pointer to the task preempted by the current exception
|
||||
*
|
||||
* designed to be called from interrupt context.
|
||||
*/
|
||||
static task_ *__get_task_scheduled(void)
|
||||
{
|
||||
unsigned sp;
|
||||
|
||||
asm("mrs %0, psp":"=r"(sp));
|
||||
return (task_ *)((sp - 16) & ~(TASK_SIZE-1));
|
||||
}
|
||||
|
||||
|
||||
static inline task_ *__task_id_to_ptr(task_id_t id)
|
||||
{
|
||||
return tasks + id;
|
||||
@@ -202,23 +179,11 @@ inline int get_interrupt_context(void)
|
||||
return ret & 0x1ff; /* exception bits are the 9 LSB */
|
||||
}
|
||||
|
||||
|
||||
task_id_t task_from_addr(uint32_t addr)
|
||||
{
|
||||
task_id_t id = (addr - (uint32_t)tasks) >> TASK_SIZE_LOG2;
|
||||
if (id >= TASK_ID_COUNT)
|
||||
id = TASK_ID_INVALID;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
task_id_t task_get_current(void)
|
||||
{
|
||||
return task_from_addr((uint32_t)__get_current());
|
||||
return current_task - tasks;
|
||||
}
|
||||
|
||||
|
||||
uint32_t *task_get_event_bitmap(task_id_t tskid)
|
||||
{
|
||||
task_ *tsk = __task_id_to_ptr(tskid);
|
||||
@@ -255,14 +220,17 @@ void svc_handler(int desched, task_id_t resched)
|
||||
}
|
||||
#endif
|
||||
|
||||
current = __get_task_scheduled();
|
||||
current = current_task;
|
||||
#ifdef CONFIG_OVERFLOW_DETECT
|
||||
ASSERT(current->guard == GUARD_VALUE);
|
||||
#endif
|
||||
|
||||
if (desched && !current->events) {
|
||||
/* Remove our own ready bit */
|
||||
tasks_ready &= ~(1 << (current-tasks));
|
||||
/*
|
||||
* Remove our own ready bit (current - tasks is same as
|
||||
* task_get_current())
|
||||
*/
|
||||
tasks_ready &= ~(1 << (current - tasks));
|
||||
}
|
||||
tasks_ready |= 1 << resched;
|
||||
|
||||
@@ -292,6 +260,7 @@ void svc_handler(int desched, task_id_t resched)
|
||||
#ifdef CONFIG_TASK_PROFILING
|
||||
task_switches++;
|
||||
#endif
|
||||
current_task = next;
|
||||
__switchto(current, next);
|
||||
}
|
||||
|
||||
@@ -343,7 +312,7 @@ void task_resched_if_needed(void *excep_return)
|
||||
|
||||
static uint32_t __wait_evt(int timeout_us, task_id_t resched)
|
||||
{
|
||||
task_ *tsk = __get_current();
|
||||
task_ *tsk = current_task;
|
||||
task_id_t me = tsk - tasks;
|
||||
uint32_t evt;
|
||||
int ret;
|
||||
@@ -488,7 +457,7 @@ void mutex_lock(struct mutex *mtx)
|
||||
void mutex_unlock(struct mutex *mtx)
|
||||
{
|
||||
uint32_t waiters;
|
||||
task_ *tsk = __get_current();
|
||||
task_ *tsk = current_task;
|
||||
|
||||
__asm__ __volatile__(" ldr %0, [%2]\n"
|
||||
" str %3, [%1]\n"
|
||||
|
||||
@@ -34,7 +34,7 @@ void watchdog_trace(uint32_t excep_lr, uint32_t excep_sp)
|
||||
if ((excep_lr & 0xf) == 1)
|
||||
uart_puts("(exc) ###\n");
|
||||
else
|
||||
uart_printf("(task %d) ###\n", task_from_addr(psp));
|
||||
uart_printf("(task %d) ###\n", task_get_current());
|
||||
/* Ensure this debug message is always flushed to the UART */
|
||||
uart_emergency_flush();
|
||||
|
||||
|
||||
@@ -50,16 +50,9 @@ static inline void task_wake(task_id_t tskid)
|
||||
task_set_event(tskid, TASK_EVENT_WAKE, 0);
|
||||
}
|
||||
|
||||
/* Return the identifier of the task currently running.
|
||||
*
|
||||
* When called in interrupt context, returns TASK_ID_INVALID. */
|
||||
/* Return the identifier of the task currently running. */
|
||||
task_id_t task_get_current(void);
|
||||
|
||||
/* Convert an address to the corresponding task ID. The address may be a stack
|
||||
* pointer or the task data for a task. Returns TASK_ID_INVALID if the address
|
||||
* does not correspond to a task. */
|
||||
task_id_t task_from_addr(uint32_t addr);
|
||||
|
||||
/* Return a pointer to the bitmap of events of the task. */
|
||||
uint32_t *task_get_event_bitmap(task_id_t tsk);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user