From 59e68964cd712afd71d5a7b8efd3b54f8c499892 Mon Sep 17 00:00:00 2001 From: rusEfi Date: Fri, 17 Apr 2015 19:08:49 -0400 Subject: [PATCH] auto-sync --- .../system/SingleTimerExecutor.cpp | 3 ++ firmware/controllers/system/event_queue.cpp | 44 +++++++++++-------- firmware/controllers/system/event_queue.h | 11 ++++- unit_tests/test_trigger_decoder.cpp | 5 +-- 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/firmware/controllers/system/SingleTimerExecutor.cpp b/firmware/controllers/system/SingleTimerExecutor.cpp index 9cf39ae11b..5522b5d525 100644 --- a/firmware/controllers/system/SingleTimerExecutor.cpp +++ b/firmware/controllers/system/SingleTimerExecutor.cpp @@ -54,6 +54,9 @@ static void executorCallback(void *arg) { Executor::Executor() { reentrantFlag = false; + /** + * todo: a good comment + */ queue.setLateDelay(US2NT(100)); } diff --git a/firmware/controllers/system/event_queue.cpp b/firmware/controllers/system/event_queue.cpp index c6a04a6dc5..f2effa9e41 100644 --- a/firmware/controllers/system/event_queue.cpp +++ b/firmware/controllers/system/event_queue.cpp @@ -25,16 +25,18 @@ bool EventQueue::checkIfPending(scheduling_s *scheduling) { return assertNotInList(head, scheduling); } -void EventQueue::insertTask(scheduling_s *scheduling, uint64_t timeX, schfunc_t callback, void *param) { +/** + * @return true if inserted into the head of the list + */ +bool_t EventQueue::insertTask(scheduling_s *scheduling, uint64_t timeX, schfunc_t callback, void *param) { #if EFI_UNIT_TEST assertListIsSorted(); #endif - if (callback == NULL) - firmwareError("NULL callback"); + efiAssert(callback != NULL, "NULL callback", false); int alreadyPending = checkIfPending(scheduling); if (alreadyPending) - return; + return false; scheduling->momentX = timeX; scheduling->callback = callback; @@ -42,6 +44,10 @@ void EventQueue::insertTask(scheduling_s *scheduling, uint64_t timeX, schfunc_t if (head == NULL || timeX < head->momentX) { LL_PREPEND(head, scheduling); +#if EFI_UNIT_TEST + assertListIsSorted(); +#endif + return true; } else { scheduling_s *insertPosition = head; while (insertPosition->next != NULL && insertPosition->next->momentX < timeX) { @@ -50,23 +56,19 @@ void EventQueue::insertTask(scheduling_s *scheduling, uint64_t timeX, schfunc_t scheduling->next = insertPosition->next; insertPosition->next = scheduling; - } #if EFI_UNIT_TEST - assertListIsSorted(); + assertListIsSorted(); #endif + return false; + } } -//void EventQueue::insertTask(scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param) { -// insertTask(scheduling, getTimeNowUs(), delayUs, callback, param); -//} - /** * On this layer it does not matter which units are used - us, ms ot nt. - * Get the timestamp of the soonest pending action + * @return Get the timestamp of the soonest pending action, skipping all the actions in the past */ uint64_t EventQueue::getNextEventTime(uint64_t nowX) { scheduling_s * current; - // this is a large value which is expected to be larger than any real time uint64_t nextTimeUs = EMPTY_QUEUE; int counter = 0; @@ -78,18 +80,18 @@ uint64_t EventQueue::getNextEventTime(uint64_t nowX) { } if (current->momentX <= nowX) { /** + * We are here if action timestamp is in the past + * * looks like we end up here after 'writeconfig' (which freezes the firmware) - we are late * for the next scheduled event */ - uint64_t mock = nowX + lateDelay; - if (mock < nextTimeUs) - nextTimeUs = mock; + uint64_t aBitInTheFuture = nowX + lateDelay; + return aBitInTheFuture; } else { - if (current->momentX < nextTimeUs) - nextTimeUs = current->momentX; + return current->momentX; } } - return nextTimeUs; + return EMPTY_QUEUE; } // static scheduling_s * longScheduling; @@ -118,6 +120,12 @@ int EventQueue::executeAll(uint64_t now) { executionCounter++; LL_DELETE(head, current); LL_PREPEND(executionList, current); + } else { + /** + * The list is sorted. Once we find one action in the future, all the remaining ones + * are also in the future. + */ + break; } } #if EFI_UNIT_TEST diff --git a/firmware/controllers/system/event_queue.h b/firmware/controllers/system/event_queue.h index 0b88c96451..0f31462995 100644 --- a/firmware/controllers/system/event_queue.h +++ b/firmware/controllers/system/event_queue.h @@ -11,6 +11,9 @@ #ifndef EVENT_SCHEDULER_H_ #define EVENT_SCHEDULER_H_ +/** + * this is a large value which is expected to be larger than any real time + */ #define EMPTY_QUEUE 0x0FFFFFFFFFFFFFFFLL #define QUEUE_LENGTH_LIMIT 1000 @@ -43,7 +46,10 @@ class EventQueue { public: EventQueue(); - void insertTask(scheduling_s *scheduling, uint64_t timeX, schfunc_t callback, void *param); + /** + * O(size) + */ + bool_t insertTask(scheduling_s *scheduling, uint64_t timeX, schfunc_t callback, void *param); int executeAll(uint64_t now); @@ -56,6 +62,9 @@ public: void assertListIsSorted(); private: bool checkIfPending(scheduling_s *scheduling); + /** + * this list is sorted + */ scheduling_s *head; uint64_t lateDelay; }; diff --git a/unit_tests/test_trigger_decoder.cpp b/unit_tests/test_trigger_decoder.cpp index bc1cecfe99..c929d9c951 100644 --- a/unit_tests/test_trigger_decoder.cpp +++ b/unit_tests/test_trigger_decoder.cpp @@ -400,7 +400,7 @@ static void testRpmCalculator(void) { // engine.rpmCalculator = ð.rpmState; prepareTimingMap(PASS_ENGINE_PARAMETER_F); - assertEqualsM("queue size", 0, schedulingQueue.size()); + assertEqualsM("queue size/0", 0, schedulingQueue.size()); debugSignalExecutor = true; @@ -415,10 +415,9 @@ static void testRpmCalculator(void) { assertEqualsM("dwell offset", 14.0316, ilist->elements[0].dwellPosition.angleOffset); assertEqualsM("index #2", 0, eth.triggerCentral.triggerState.getCurrentIndex()); - assertEqualsM("queue size", 6, schedulingQueue.size()); + assertEqualsM("queue size/6", 6, schedulingQueue.size()); scheduling_s *ev1 = schedulingQueue.getForUnitText(0); assertREquals((void*)ev1->callback, (void*)turnPinHigh); - assertREquals((void*)&enginePins.coils[3], ev1->param); assertEqualsM("ev 1", 245000, ev1->momentX); assertEqualsM("ev 2", 245000, schedulingQueue.getForUnitText(1)->momentX);