mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-11 18:35:28 +00:00
hooks: Move HOOK_INIT to after task switching.
This commit changes the way in which tasks are started. Instead of having all tasks marked as ready to run upon initialization, only the hooks task is marked as ready to run. HOOK_INITs are now run at the beginning of the hooks task. After the HOOK_INITs, the hooks task calls back to enable the rest of the tasks, reschedules, and proceeds as usual. This also allows the removal of checks for task_start_called(). BUG=chrome-os-partner:27226 BRANCH=None TEST=Built and flash EC image for samus and verified that EC boot was successful as well as AP boot. Additionally, verified that charging, keyboard, tap-for-battery were all still functional. TEST=make -j buildall tests Change-Id: Iea53670222c803c2985e9c86c96974386888a4fe Signed-off-by: Aseda Aboagye <aaboagye@google.com> Reviewed-on: https://chromium-review.googlesource.com/283657 Reviewed-by: Alec Berg <alecaberg@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Commit-Queue: Aseda Aboagye <aaboagye@chromium.org> Tested-by: Aseda Aboagye <aaboagye@chromium.org>
This commit is contained in:
committed by
ChromeOS Commit Bot
parent
41b538d4c6
commit
fbc84dc565
@@ -131,11 +131,6 @@ void hook_notify(enum hook_type type)
|
||||
#endif
|
||||
}
|
||||
|
||||
void hook_init(void)
|
||||
{
|
||||
hook_notify(HOOK_INIT);
|
||||
}
|
||||
|
||||
int hook_call_deferred(void (*routine)(void), int us)
|
||||
{
|
||||
const struct deferred_data *p;
|
||||
@@ -180,6 +175,12 @@ void hook_task(void)
|
||||
|
||||
hook_task_started = 1;
|
||||
|
||||
/* Call HOOK_INIT hooks. */
|
||||
hook_notify(HOOK_INIT);
|
||||
|
||||
/* Now, enable the rest of the tasks. */
|
||||
task_enable_all_tasks();
|
||||
|
||||
while (1) {
|
||||
uint64_t t = get_time().val;
|
||||
int next = 0;
|
||||
|
||||
@@ -160,9 +160,6 @@ test_mockable __keep int main(void)
|
||||
check_rw_signature();
|
||||
#endif
|
||||
|
||||
/* Initialize the hook library. This calls HOOK_INIT hooks. */
|
||||
hook_init();
|
||||
|
||||
/*
|
||||
* Print the init time. Not completely accurate because it can't take
|
||||
* into account the time before timer_init(), but it'll at least catch
|
||||
|
||||
@@ -139,9 +139,11 @@ static int need_resched_or_profiling;
|
||||
/*
|
||||
* Bitmap of all tasks ready to be run.
|
||||
*
|
||||
* Currently all tasks are enabled at startup.
|
||||
* Start off with only the hooks task marked as ready such that all the modules
|
||||
* can do their init within a task switching context. The hooks task will then
|
||||
* make a call to enable all tasks.
|
||||
*/
|
||||
static uint32_t tasks_ready = (1<<TASK_ID_COUNT) - 1;
|
||||
static uint32_t tasks_ready = (1 << TASK_ID_HOOKS);
|
||||
|
||||
static int start_called; /* Has task swapping started */
|
||||
|
||||
@@ -412,6 +414,14 @@ uint32_t task_wait_event_mask(uint32_t event_mask, int timeout_us)
|
||||
return events & event_mask;
|
||||
}
|
||||
|
||||
void task_enable_all_tasks(void)
|
||||
{
|
||||
/* Mark all tasks as ready to run. */
|
||||
tasks_ready = (1 << TASK_ID_COUNT) - 1;
|
||||
/* Reschedule the highest priority task. */
|
||||
__schedule(0, 0);
|
||||
}
|
||||
|
||||
void task_enable_irq(int irq)
|
||||
{
|
||||
CPU_NVIC_EN(irq / 32) = 1 << (irq % 32);
|
||||
|
||||
@@ -126,9 +126,11 @@ static task_ *current_task = (task_ *)scratchpad;
|
||||
/*
|
||||
* Bitmap of all tasks ready to be run.
|
||||
*
|
||||
* Currently all tasks are enabled at startup.
|
||||
* Start off with only the hooks task marked as ready such that all the modules
|
||||
* can do their init within a task switching context. The hooks task will then
|
||||
* make a call to enable all tasks.
|
||||
*/
|
||||
static uint32_t tasks_ready = (1<<TASK_ID_COUNT) - 1;
|
||||
static uint32_t tasks_ready = (1 << TASK_ID_HOOKS);
|
||||
|
||||
static int start_called; /* Has task swapping started */
|
||||
|
||||
@@ -432,6 +434,14 @@ uint32_t task_wait_event_mask(uint32_t event_mask, int timeout_us)
|
||||
return events & event_mask;
|
||||
}
|
||||
|
||||
void task_enable_all_tasks(void)
|
||||
{
|
||||
/* Mark all tasks as ready to run. */
|
||||
tasks_ready = (1 << TASK_ID_COUNT) - 1;
|
||||
/* Reschedule the highest priority task. */
|
||||
__schedule(0, 0);
|
||||
}
|
||||
|
||||
void task_enable_irq(int irq)
|
||||
{
|
||||
CPU_NVIC_EN(0) = 1 << irq;
|
||||
|
||||
@@ -45,7 +45,6 @@ int main(int argc, char **argv)
|
||||
#ifdef HAS_TASK_KEYSCAN
|
||||
keyboard_scan_init();
|
||||
#endif
|
||||
hook_init();
|
||||
uart_init();
|
||||
|
||||
if (system_jumped_to_this_image()) {
|
||||
|
||||
@@ -56,6 +56,8 @@ static int has_interrupt_generator = 1;
|
||||
|
||||
static __thread task_id_t my_task_id; /* thread local task id */
|
||||
|
||||
static void task_enable_all_tasks_callback(void);
|
||||
|
||||
#define TASK(n, r, d, s) void r(void *);
|
||||
CONFIG_TASK_LIST
|
||||
CONFIG_TEST_TASK_LIST
|
||||
@@ -331,6 +333,7 @@ static int fast_forward(void)
|
||||
return TASK_ID_IDLE;
|
||||
|
||||
if (task_id != TASK_ID_INVALID &&
|
||||
tasks[task_id].thread != (pthread_t)NULL &&
|
||||
tasks[task_id].wake_time.val < generator_sleep_deadline.val) {
|
||||
force_time(tasks[task_id].wake_time);
|
||||
return task_id;
|
||||
@@ -356,8 +359,15 @@ void task_scheduler(void)
|
||||
now = get_time();
|
||||
i = TASK_ID_COUNT - 1;
|
||||
while (i >= 0) {
|
||||
if (tasks[i].event || now.val >= tasks[i].wake_time.val)
|
||||
break;
|
||||
/*
|
||||
* Only tasks with spawned threads are valid to be
|
||||
* resumed.
|
||||
*/
|
||||
if (tasks[i].thread) {
|
||||
if (tasks[i].event ||
|
||||
now.val >= tasks[i].wake_time.val)
|
||||
break;
|
||||
}
|
||||
--i;
|
||||
}
|
||||
if (i < 0)
|
||||
@@ -404,7 +414,7 @@ void *_task_int_generator_start(void *d)
|
||||
|
||||
int task_start(void)
|
||||
{
|
||||
int i;
|
||||
int i = TASK_ID_HOOKS;
|
||||
|
||||
task_register_interrupt();
|
||||
|
||||
@@ -414,23 +424,25 @@ int task_start(void)
|
||||
|
||||
pthread_mutex_lock(&run_lock);
|
||||
|
||||
for (i = 0; i < TASK_ID_COUNT; ++i) {
|
||||
tasks[i].event = TASK_EVENT_WAKE;
|
||||
tasks[i].wake_time.val = ~0ull;
|
||||
tasks[i].started = 0;
|
||||
pthread_cond_init(&tasks[i].resume, NULL);
|
||||
pthread_create(&tasks[i].thread, NULL, _task_start_impl,
|
||||
(void *)(uintptr_t)i);
|
||||
pthread_cond_wait(&scheduler_cond, &run_lock);
|
||||
/*
|
||||
* Interrupt lock is grabbed by the task which just started.
|
||||
* Let's unlock it so the next task can be started.
|
||||
*/
|
||||
pthread_mutex_unlock(&interrupt_lock);
|
||||
}
|
||||
/*
|
||||
* Initialize the hooks task first. After its init, it will callback to
|
||||
* enable the remaining tasks.
|
||||
*/
|
||||
tasks[i].event = TASK_EVENT_WAKE;
|
||||
tasks[i].wake_time.val = ~0ull;
|
||||
tasks[i].started = 0;
|
||||
pthread_cond_init(&tasks[i].resume, NULL);
|
||||
pthread_create(&tasks[i].thread, NULL, _task_start_impl,
|
||||
(void *)(uintptr_t)i);
|
||||
pthread_cond_wait(&scheduler_cond, &run_lock);
|
||||
/*
|
||||
* Interrupt lock is grabbed by the task which just started.
|
||||
* Let's unlock it so the next task can be started.
|
||||
*/
|
||||
pthread_mutex_unlock(&interrupt_lock);
|
||||
|
||||
/*
|
||||
* All tasks are now waiting in task_wait_event(). Lock interrupt_lock
|
||||
* The hooks task is waiting in task_wait_event(). Lock interrupt_lock
|
||||
* here so the first task chosen sees it locked.
|
||||
*/
|
||||
pthread_mutex_lock(&interrupt_lock);
|
||||
@@ -438,7 +450,46 @@ int task_start(void)
|
||||
pthread_create(&interrupt_thread, NULL,
|
||||
_task_int_generator_start, NULL);
|
||||
|
||||
/*
|
||||
* Tell the hooks task to continue so that it can call back to enable
|
||||
* the other tasks.
|
||||
*/
|
||||
pthread_cond_signal(&tasks[i].resume);
|
||||
pthread_cond_wait(&scheduler_cond, &run_lock);
|
||||
task_enable_all_tasks_callback();
|
||||
|
||||
task_scheduler();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void task_enable_all_tasks_callback(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Initialize the remaning tasks. */
|
||||
for (i = 0; i < TASK_ID_COUNT; ++i) {
|
||||
if (tasks[i].thread != (pthread_t)NULL)
|
||||
continue;
|
||||
|
||||
tasks[i].event = TASK_EVENT_WAKE;
|
||||
tasks[i].wake_time.val = ~0ull;
|
||||
tasks[i].started = 0;
|
||||
pthread_cond_init(&tasks[i].resume, NULL);
|
||||
pthread_create(&tasks[i].thread, NULL, _task_start_impl,
|
||||
(void *)(uintptr_t)i);
|
||||
/*
|
||||
* Interrupt lock is grabbed by the task which just started.
|
||||
* Let's unlock it so the next task can be started.
|
||||
*/
|
||||
pthread_mutex_unlock(&interrupt_lock);
|
||||
pthread_cond_wait(&scheduler_cond, &run_lock);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void task_enable_all_tasks(void)
|
||||
{
|
||||
/* Signal to the scheduler to enable the remaining tasks. */
|
||||
pthread_cond_signal(&scheduler_cond);
|
||||
}
|
||||
|
||||
@@ -139,9 +139,11 @@ int need_resched;
|
||||
/*
|
||||
* Bitmap of all tasks ready to be run.
|
||||
*
|
||||
* Currently all tasks are enabled at startup.
|
||||
* Start off with only the hooks task marked as ready such that all the modules
|
||||
* can do their init within a task switching context. The hooks task will then
|
||||
* make a call to enable all tasks.
|
||||
*/
|
||||
static uint32_t tasks_ready = (1<<TASK_ID_COUNT) - 1;
|
||||
static uint32_t tasks_ready = (1 << TASK_ID_HOOKS);
|
||||
|
||||
static int start_called; /* Has task swapping started */
|
||||
|
||||
@@ -306,6 +308,14 @@ static void set_int_priority(uint32_t val)
|
||||
asm volatile ("mtsr %0, $INT_PRI" : : "r"(val));
|
||||
}
|
||||
|
||||
void task_enable_all_tasks(void)
|
||||
{
|
||||
/* Mark all tasks are ready to run. */
|
||||
tasks_ready = (1 << TASK_ID_COUNT) - 1;
|
||||
/* Reschedule the highest priority task. */
|
||||
__schedule(0, 0, 0);
|
||||
}
|
||||
|
||||
void task_enable_irq(int irq)
|
||||
{
|
||||
int cpu_int = chip_enable_irq(irq);
|
||||
|
||||
@@ -167,11 +167,6 @@ struct hook_data {
|
||||
int priority;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the hooks library.
|
||||
*/
|
||||
void hook_init(void);
|
||||
|
||||
/**
|
||||
* Call all the hook routines of a specified type.
|
||||
*
|
||||
|
||||
@@ -183,6 +183,11 @@ int task_start_called(void);
|
||||
void task_clear_fp_used(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Mark all tasks as ready to run and reschedule the highest priority task.
|
||||
*/
|
||||
void task_enable_all_tasks(void);
|
||||
|
||||
/**
|
||||
* Enable an interrupt.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user