diff --git a/firmware/controllers/engine_controller.cpp b/firmware/controllers/engine_controller.cpp index 2231d0a3fb..99aa566e39 100644 --- a/firmware/controllers/engine_controller.cpp +++ b/firmware/controllers/engine_controller.cpp @@ -702,7 +702,7 @@ void initEngineContoller(DECLARE_ENGINE_PARAMETER_SUFFIX) { * UNUSED_SIZE constants. */ #ifndef RAM_UNUSED_SIZE -#define RAM_UNUSED_SIZE 3000 +#define RAM_UNUSED_SIZE 4000 #endif #ifndef CCM_UNUSED_SIZE #define CCM_UNUSED_SIZE 2000 diff --git a/firmware/controllers/system/timer/event_queue.cpp b/firmware/controllers/system/timer/event_queue.cpp index f73f7da454..83e034c15c 100644 --- a/firmware/controllers/system/timer/event_queue.cpp +++ b/firmware/controllers/system/timer/event_queue.cpp @@ -37,7 +37,7 @@ bool EventQueue::insertTask(scheduling_s *scheduling, efitime_t timeX, action_s // please note that simulator does not use this code at all - simulator uses signal_executor_sleep - if (scheduling->isScheduled) { + if (scheduling->action) { #if EFI_UNIT_TEST if (verboseMode) { printf("Already scheduled was %d\r\n", (int)scheduling->momentX); @@ -49,7 +49,6 @@ bool EventQueue::insertTask(scheduling_s *scheduling, efitime_t timeX, action_s scheduling->momentX = timeX; scheduling->action = action; - scheduling->isScheduled = true; if (head == NULL || timeX < head->momentX) { // here we insert into head of the linked list @@ -157,16 +156,19 @@ bool EventQueue::executeOne(efitime_t now) { // step the head forward, unlink this element, clear scheduled flag head = current->nextScheduling_s; current->nextScheduling_s = nullptr; - current->isScheduled = false; + + // Grab the action but clear it in the event so we can reschedule from the action's execution + auto action = current->action; + current->action = {}; #if EFI_UNIT_TEST - printf("QUEUE: execute current=%d param=%d\r\n", (long)current, (long)current->action.getArgument()); + printf("QUEUE: execute current=%d param=%d\r\n", (long)current, (long)action.getArgument()); #endif // Execute the current element { ScopePerf perf2(PE::EventQueueExecuteCallback); - current->action.execute(); + action.execute(); } #if EFI_UNIT_TEST @@ -221,7 +223,6 @@ void EventQueue::clear(void) { // Reset this element x->momentX = 0; - x->isScheduled = false; x->nextScheduling_s = nullptr; x->action = {}; } diff --git a/firmware/controllers/system/timer/scheduler.h b/firmware/controllers/system/timer/scheduler.h index a1f66acc19..ffa761a020 100644 --- a/firmware/controllers/system/timer/scheduler.h +++ b/firmware/controllers/system/timer/scheduler.h @@ -12,6 +12,7 @@ typedef void (*schfunc_t)(void *); class action_s { public: + // Default constructor constructs null action (ie, implicit bool conversion returns false) action_s() = default; // Allow implicit conversion from schfunc_t to action_s @@ -27,6 +28,10 @@ public: schfunc_t getCallback() const; void * getArgument() const; + operator bool() const { + return callback != nullptr; + } + private: schfunc_t callback = nullptr; void *param = nullptr; @@ -35,6 +40,7 @@ private: /** * This structure holds information about an event scheduled in the future: when to execute what callback with what parameters */ +#pragma pack(push, 4) struct scheduling_s { #if EFI_SIGNAL_EXECUTOR_SLEEP virtual_timer_t timer; @@ -44,7 +50,6 @@ struct scheduling_s { * timestamp represented as 64-bit value of ticks since MCU start */ volatile efitime_t momentX = 0; - bool isScheduled = false; /** * Scheduler implementation uses a sorted linked list of these scheduling records. @@ -53,6 +58,7 @@ struct scheduling_s { action_s action; }; +#pragma pack(pop) struct ExecutorInterface { /**