mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
emulator: Fix handling of early IRQs.
Since the interrupt generator is now spawned right after the hooks task and the generator can generate interrupts whenever it wants, it's possible for an interrupt to fire before task switching is enabled. When this happens, the main thread needs to be suspended so that the IRQ can be serviced. BRANCH=None BUG=None TEST="make clobber && make -j buildall tests" several times." Change-Id: I5fb4f17666e3db9c670c4352bb36b84e4606dfa0 Signed-off-by: Aseda Aboagye <aaboagye@google.com> Reviewed-on: https://chromium-review.googlesource.com/285634 Tested-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Commit-Queue: Aseda Aboagye <aaboagye@chromium.org> Trybot-Ready: Aseda Aboagye <aaboagye@chromium.org>
This commit is contained in:
committed by
ChromeOS Commit Bot
parent
482a0811d6
commit
a21650f05f
@@ -23,4 +23,15 @@ pthread_t task_get_thread(task_id_t tskid);
|
||||
*/
|
||||
task_id_t task_get_running(void);
|
||||
|
||||
/**
|
||||
* Initializes the interrupt semaphore and associates a signal handler with
|
||||
* SIGNAL_INTERRUPT.
|
||||
*/
|
||||
void task_register_interrupt(void);
|
||||
|
||||
/**
|
||||
* Returns the process ID of the calling process.
|
||||
*/
|
||||
pid_t getpid(void);
|
||||
|
||||
#endif /* __CROS_EC_HOST_TASK_H */
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "console.h"
|
||||
#include "flash.h"
|
||||
#include "hooks.h"
|
||||
#include "host_task.h"
|
||||
#include "keyboard_scan.h"
|
||||
#include "stack_trace.h"
|
||||
#include "system.h"
|
||||
@@ -31,6 +32,12 @@ int main(int argc, char **argv)
|
||||
{
|
||||
__prog_name = argv[0];
|
||||
|
||||
/*
|
||||
* In order to properly service IRQs before task switching is enabled,
|
||||
* we must set up our signal handler for the main thread.
|
||||
*/
|
||||
task_register_interrupt();
|
||||
|
||||
task_register_tracedump();
|
||||
|
||||
register_test_end_hook();
|
||||
|
||||
@@ -125,7 +125,7 @@ static void _task_execute_isr(int sig)
|
||||
in_interrupt = 0;
|
||||
}
|
||||
|
||||
static void task_register_interrupt(void)
|
||||
void task_register_interrupt(void)
|
||||
{
|
||||
sem_init(&interrupt_sem, 0, 0);
|
||||
signal(SIGNAL_INTERRUPT, _task_execute_isr);
|
||||
@@ -133,6 +133,7 @@ static void task_register_interrupt(void)
|
||||
|
||||
void task_trigger_test_interrupt(void (*isr)(void))
|
||||
{
|
||||
pid_t main_pid;
|
||||
pthread_mutex_lock(&interrupt_lock);
|
||||
if (interrupt_disabled) {
|
||||
pthread_mutex_unlock(&interrupt_lock);
|
||||
@@ -141,7 +142,12 @@ void task_trigger_test_interrupt(void (*isr)(void))
|
||||
|
||||
/* Suspend current task and excute ISR */
|
||||
pending_isr = isr;
|
||||
pthread_kill(tasks[running_task_id].thread, SIGNAL_INTERRUPT);
|
||||
if (task_started) {
|
||||
pthread_kill(tasks[running_task_id].thread, SIGNAL_INTERRUPT);
|
||||
} else {
|
||||
main_pid = getpid();
|
||||
kill(main_pid, SIGNAL_INTERRUPT);
|
||||
}
|
||||
|
||||
/* Wait for ISR to complete */
|
||||
sem_wait(&interrupt_sem);
|
||||
@@ -416,8 +422,6 @@ int task_start(void)
|
||||
{
|
||||
int i = TASK_ID_HOOKS;
|
||||
|
||||
task_register_interrupt();
|
||||
|
||||
pthread_mutex_init(&run_lock, NULL);
|
||||
pthread_mutex_init(&interrupt_lock, NULL);
|
||||
pthread_cond_init(&scheduler_cond, NULL);
|
||||
|
||||
Reference in New Issue
Block a user