From 2f01f8759cd35a9112a9ed70222b1f8482a452a8 Mon Sep 17 00:00:00 2001 From: rusefi Date: Wed, 9 Jan 2019 00:53:54 -0500 Subject: [PATCH] The Big Refactoring of 2019: scheduler should not be global #655 --- firmware/controllers/algo/engine.h | 22 ++++++++++++++++++- .../controllers/system/SingleTimerExecutor.h | 2 +- firmware/controllers/system/scheduler.h | 6 +++++ .../system/signal_executor_sleep.cpp | 8 +++++-- .../system/signal_executor_sleep.h | 7 ++++++ .../trigger/main_trigger_callback.cpp | 6 ++--- unit_tests/global_execution_queue.cpp | 8 +++++++ unit_tests/global_execution_queue.h | 18 +++++++++++++++ 8 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 unit_tests/global_execution_queue.h diff --git a/firmware/controllers/algo/engine.h b/firmware/controllers/algo/engine.h index 291c0b126a..894719a082 100644 --- a/firmware/controllers/algo/engine.h +++ b/firmware/controllers/algo/engine.h @@ -2,7 +2,7 @@ * @file engine.h * * @date May 21, 2014 - * @author Andrey Belomutskiy, (c) 2012-2017 + * @author Andrey Belomutskiy, (c) 2012-2019 */ #ifndef H_ENGINE_H_ #define H_ENGINE_H_ @@ -19,6 +19,16 @@ #include "accel_enrichment.h" #include "trigger_central.h" +#if EFI_SIGNAL_EXECUTOR_ONE_TIMER +// PROD real firmware uses this implementation +#include "SingleTimerExecutor.h" +#endif /* EFI_SIGNAL_EXECUTOR_ONE_TIMER */ +#if EFI_SIGNAL_EXECUTOR_SLEEP +#endif /* EFI_SIGNAL_EXECUTOR_SLEEP */ +#if EFI_UNIT_TEST +#include "global_execution_queue.h" +#endif /* EFI_UNIT_TEST */ + #define MOCK_ADC_SIZE 16 class MockAdcState { @@ -316,6 +326,16 @@ public: InjectionSignalPair fuelActuators[INJECTION_PIN_COUNT]; IgnitionEventList ignitionEvents; + // a pointer with interface type would make this code nicer but would carry extra runtime + // cost to resolve pointer, we use instances as a micro optimization +#if EFI_SIGNAL_EXECUTOR_ONE_TIMER + Executor executor; +#endif +#if EFI_SIGNAL_EXECUTOR_SLEEP +#endif +#if EFI_UNIT_TEST + TestExecutor executor; +#endif #if EFI_ENGINE_CONTROL || defined(__DOXYGEN__) FuelSchedule injectionEvents; diff --git a/firmware/controllers/system/SingleTimerExecutor.h b/firmware/controllers/system/SingleTimerExecutor.h index 7e46b4d31c..1ee225d883 100644 --- a/firmware/controllers/system/SingleTimerExecutor.h +++ b/firmware/controllers/system/SingleTimerExecutor.h @@ -11,7 +11,7 @@ #include "scheduler.h" #include "event_queue.h" -class Executor { +class Executor : public ExecutorInterface { public: Executor(); void scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, schfunc_t callback, void *param); diff --git a/firmware/controllers/system/scheduler.h b/firmware/controllers/system/scheduler.h index acd62e3688..085f952498 100644 --- a/firmware/controllers/system/scheduler.h +++ b/firmware/controllers/system/scheduler.h @@ -29,7 +29,13 @@ public: /** * see also scheduleByAngle */ +// Deprecated see https://github.com/rusefi/rusefi/issues/655 void scheduleForLater(scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param); +// Deprecated see https://github.com/rusefi/rusefi/issues/655 void scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t time, schfunc_t callback, void *param); +class ExecutorInterface { + virtual void scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, schfunc_t callback, void *param) = 0; +}; + #endif /* SCHEDULER_H_ */ diff --git a/firmware/controllers/system/signal_executor_sleep.cpp b/firmware/controllers/system/signal_executor_sleep.cpp index 8f72f43cf1..a2df2f116a 100644 --- a/firmware/controllers/system/signal_executor_sleep.cpp +++ b/firmware/controllers/system/signal_executor_sleep.cpp @@ -34,8 +34,12 @@ #if EFI_SIGNAL_EXECUTOR_SLEEP || defined(__DOXYGEN__) -void scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t time, schfunc_t callback, void *param) { - scheduleForLater(scheduling, time - getTimeNowUs(), callback, param); +void scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, schfunc_t callback, void *param) { + scheduleForLater(scheduling, timeUs - getTimeNowUs(), callback, param); +} + +void SleepExecutor::scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, schfunc_t callback, void *param) { + scheduleForLater(scheduling, timeUs - getTimeNowUs(), callback, param); } static void timerCallback(scheduling_s *scheduling) { diff --git a/firmware/controllers/system/signal_executor_sleep.h b/firmware/controllers/system/signal_executor_sleep.h index d2c370c88d..50585ee08b 100644 --- a/firmware/controllers/system/signal_executor_sleep.h +++ b/firmware/controllers/system/signal_executor_sleep.h @@ -8,4 +8,11 @@ #ifndef SIGNAL_EXECUTOR_SLEEP_H_ #define SIGNAL_EXECUTOR_SLEEP_H_ +#include "scheduler.h" + +class SleepExecutor : public ExecutorInterface { +public: + void scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, schfunc_t callback, void *param); +}; + #endif /* SIGNAL_EXECUTOR_SLEEP_H_ */ diff --git a/firmware/controllers/trigger/main_trigger_callback.cpp b/firmware/controllers/trigger/main_trigger_callback.cpp index 72b12fd1cf..9be947a441 100644 --- a/firmware/controllers/trigger/main_trigger_callback.cpp +++ b/firmware/controllers/trigger/main_trigger_callback.cpp @@ -198,7 +198,7 @@ void seTurnPinLow(InjectionSignalPair *pair) { ENGINE(injectionEvents.addFuelEventsForCylinder(pair->event->ownIndex PASS_ENGINE_PARAMETER_SUFFIX)); } -static void sescheduleByTimestamp(scheduling_s *scheduling, efitimeus_t time, schfunc_t callback, InjectionSignalPair *pair) { +static void sescheduleByTimestamp(scheduling_s *scheduling, efitimeus_t time, schfunc_t callback, InjectionSignalPair *pair DECLARE_ENGINE_PARAMETER_SUFFIX) { #if FUEL_MATH_EXTREME_LOGGING || defined(__DOXYGEN__) InjectorOutputPin *param = pair->outputs[0]; // scheduleMsg(&sharedLogger, "schX %s %x %d", prefix, scheduling, time); @@ -341,10 +341,10 @@ static ALWAYS_INLINE void handleFuelInjectionEvent(int injEventIndex, InjectionE printf("please cancel %s %d %d\r\n", output->name, (int)getTimeNowUs(), output->overlappingCounter); #endif /* EFI_UNIT_TEST || EFI_SIMULATOR */ } else { - sescheduleByTimestamp(sUp, turnOnTime, (schfunc_t) &seTurnPinHigh, pair); + sescheduleByTimestamp(sUp, turnOnTime, (schfunc_t) &seTurnPinHigh, pair PASS_ENGINE_PARAMETER_SUFFIX); } efitimeus_t turnOffTime = nowUs + (int) (injectionStartDelayUs + durationUs); - sescheduleByTimestamp(sDown, turnOffTime, (schfunc_t) &seTurnPinLow, pair); + sescheduleByTimestamp(sDown, turnOffTime, (schfunc_t) &seTurnPinLow, pair PASS_ENGINE_PARAMETER_SUFFIX); } } diff --git a/unit_tests/global_execution_queue.cpp b/unit_tests/global_execution_queue.cpp index fb4a706f21..e11c9fb086 100644 --- a/unit_tests/global_execution_queue.cpp +++ b/unit_tests/global_execution_queue.cpp @@ -7,6 +7,7 @@ #include "signal_executor.h" #include "event_queue.h" +#include "global_execution_queue.h" // this global instance is used by integration tests via 'scheduleByTimestamp' global methods below EventQueue schedulingQueue; @@ -21,6 +22,13 @@ void scheduleForLater(scheduling_s *scheduling, int delayUs, scheduleByTimestamp(scheduling, getTimeNowUs() + delayUs, callback, param); } +void TestExecutor::scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, schfunc_t callback, void *param) { + if (debugSignalExecutor) { + printf("scheduleByTime %d\r\n", time); + } + schedulingQueue.insertTask(scheduling, time, callback, param); +} + void scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t time, schfunc_t callback, void *param) { if (debugSignalExecutor) { diff --git a/unit_tests/global_execution_queue.h b/unit_tests/global_execution_queue.h new file mode 100644 index 0000000000..132f5808ef --- /dev/null +++ b/unit_tests/global_execution_queue.h @@ -0,0 +1,18 @@ +/* + * global_execution_queue.h + * + * Created on: Jan 9, 2019 + * @author Andrey Belomutskiy, (c) 2012-2019 + */ + +#ifndef GLOBAL_EXECUTION_QUEUE_H_ +#define GLOBAL_EXECUTION_QUEUE_H_ + +#include "scheduler.h" + +class TestExecutor : public ExecutorInterface { +public: + void scheduleByTimestamp(scheduling_s *scheduling, efitimeus_t timeUs, schfunc_t callback, void *param); +}; + +#endif /* GLOBAL_EXECUTION_QUEUE_H_ */