Browse Source

Cache signals during each kernel tick to make run order more predictable

master
Adam Pippin 4 years ago
parent
commit
62890bb17c
  1. 25
      Kernel.cpp
  2. 3
      Kernel.h

25
Kernel.cpp

@ -30,7 +30,7 @@ void Kernel_setup()
last_tick_duration = 0; last_tick_duration = 0;
} }
void Kernel_start(int (*callback)(int, unsigned int), unsigned long interval) int Kernel_start(int (*callback)(int, unsigned int), unsigned long interval)
{ {
struct Task *process = Kernel_get_task(0); struct Task *process = Kernel_get_task(0);
if (process->pid == -1) if (process->pid == -1)
@ -44,6 +44,8 @@ void Kernel_start(int (*callback)(int, unsigned int), unsigned long interval)
process->run_accumulator = interval; process->run_accumulator = interval;
process->signal = SIGNAL_START | SIGNAL_TICK; process->signal = SIGNAL_START | SIGNAL_TICK;
process->running = true; process->running = true;
return process->pid;
} }
void Kernel_enable(int pid) void Kernel_enable(int pid)
@ -86,7 +88,7 @@ void Kernel_signal(unsigned int signal)
{ {
if (tasks[i].pid != 0 && tasks[i].running == true) if (tasks[i].pid != 0 && tasks[i].running == true)
{ {
tasks[i].signal |= signal; tasks[i].signal_pending |= signal;
} }
} }
} }
@ -96,7 +98,7 @@ void Kernel_signal(int pid, unsigned int signal)
struct Task *process = Kernel_get_task(pid); struct Task *process = Kernel_get_task(pid);
if (process->pid == pid) if (process->pid == pid)
{ {
process->signal |= signal; process->signal_pending |= signal;
} }
} }
@ -188,7 +190,7 @@ void Kernel_tick()
unsigned long next_tick_due = ULONG_MAX; unsigned long next_tick_due = ULONG_MAX;
int running_tasks = 0; int running_tasks = 0;
int last_exit_code = 0; int last_exit_code = 0;
for (int i=0; i<MAX_TASKS; i++) for (int i=0; i<MAX_TASKS; i++)
{ {
// If the task is initialized (non-zero PID) and is marked as running // If the task is initialized (non-zero PID) and is marked as running
@ -222,14 +224,9 @@ void Kernel_tick()
// If the process has any non-masked signals pending, run it // If the process has any non-masked signals pending, run it
if ((tasks[i].signal & tasks[i].signal_mask) != 0) if ((tasks[i].signal & tasks[i].signal_mask) != 0)
{ {
unsigned int signals = tasks[i].signal;
tasks[i].signal = SIGNAL_NONE;
// Run the task // Run the task
int task_return = (*tasks[i].callback)(tasks[i].pid, signals); int task_return = (*tasks[i].callback)(tasks[i].pid, tasks[i].signal);
// If the tasks's return value was non-zero, it has exited. // If the tasks's return value was non-zero, it has exited.
if (task_return != 0) if (task_return != 0)
{ {
@ -242,7 +239,6 @@ void Kernel_tick()
last_exit_code = task_return; last_exit_code = task_return;
} }
} }
// Check each task to see if it's the one scheduled to run on the next closest tick, and track it // Check each task to see if it's the one scheduled to run on the next closest tick, and track it
// so we can put the processor to sleep until then. // so we can put the processor to sleep until then.
@ -260,16 +256,19 @@ void Kernel_tick()
Kernel_panic(panic_msg); Kernel_panic(panic_msg);
} }
// If no signals pending, put processor to sleep until the next scheduled run of a task
// Leave the home button enabled to force a wake-up before then
bool signals_pending = false; bool signals_pending = false;
for (int i=0; i<MAX_TASKS; i++) for (int i=0; i<MAX_TASKS; i++)
{ {
tasks[i].signal = tasks[i].signal_pending;
tasks[i].signal_pending = SIGNAL_NONE;
if ((tasks[i].signal & tasks[i].signal_mask) != 0) if ((tasks[i].signal & tasks[i].signal_mask) != 0)
{ {
signals_pending = true; signals_pending = true;
} }
} }
// If no signals pending, put processor to sleep until the next scheduled run of a task
if (!signals_pending) if (!signals_pending)
{ {
esp_sleep_enable_timer_wakeup(next_tick_due * 1000); esp_sleep_enable_timer_wakeup(next_tick_due * 1000);

3
Kernel.h

@ -8,6 +8,7 @@ struct Task
unsigned long run_interval = 0; unsigned long run_interval = 0;
unsigned long run_accumulator = 0; unsigned long run_accumulator = 0;
unsigned int signal = 0; unsigned int signal = 0;
unsigned int signal_pending = 0;
unsigned int signal_mask = 0xFFFF; unsigned int signal_mask = 0xFFFF;
}; };
@ -18,7 +19,7 @@ void Kernel_tick();
void Kernel_panic(char* message); void Kernel_panic(char* message);
// Start a new process // Start a new process
void Kernel_start(int (*callback)(int, unsigned int), unsigned long interval); int Kernel_start(int (*callback)(int, unsigned int), unsigned long interval);
// Continue execution of a process // Continue execution of a process
void Kernel_enable(int pid); void Kernel_enable(int pid);
// Pause execution of a process // Pause execution of a process

Loading…
Cancel
Save