auto-sync

This commit is contained in:
rusEfi 2015-04-17 19:08:49 -04:00
parent 5baa0a0572
commit 103f28727c
4 changed files with 41 additions and 22 deletions

View File

@ -54,6 +54,9 @@ static void executorCallback(void *arg) {
Executor::Executor() { Executor::Executor() {
reentrantFlag = false; reentrantFlag = false;
/**
* todo: a good comment
*/
queue.setLateDelay(US2NT(100)); queue.setLateDelay(US2NT(100));
} }

View File

@ -25,16 +25,18 @@ bool EventQueue::checkIfPending(scheduling_s *scheduling) {
return assertNotInList<scheduling_s>(head, scheduling); return assertNotInList<scheduling_s>(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 #if EFI_UNIT_TEST
assertListIsSorted(); assertListIsSorted();
#endif #endif
if (callback == NULL) efiAssert(callback != NULL, "NULL callback", false);
firmwareError("NULL callback");
int alreadyPending = checkIfPending(scheduling); int alreadyPending = checkIfPending(scheduling);
if (alreadyPending) if (alreadyPending)
return; return false;
scheduling->momentX = timeX; scheduling->momentX = timeX;
scheduling->callback = callback; scheduling->callback = callback;
@ -42,6 +44,10 @@ void EventQueue::insertTask(scheduling_s *scheduling, uint64_t timeX, schfunc_t
if (head == NULL || timeX < head->momentX) { if (head == NULL || timeX < head->momentX) {
LL_PREPEND(head, scheduling); LL_PREPEND(head, scheduling);
#if EFI_UNIT_TEST
assertListIsSorted();
#endif
return true;
} else { } else {
scheduling_s *insertPosition = head; scheduling_s *insertPosition = head;
while (insertPosition->next != NULL && insertPosition->next->momentX < timeX) { 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; scheduling->next = insertPosition->next;
insertPosition->next = scheduling; insertPosition->next = scheduling;
}
#if EFI_UNIT_TEST #if EFI_UNIT_TEST
assertListIsSorted(); assertListIsSorted();
#endif #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. * 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) { uint64_t EventQueue::getNextEventTime(uint64_t nowX) {
scheduling_s * current; scheduling_s * current;
// this is a large value which is expected to be larger than any real time
uint64_t nextTimeUs = EMPTY_QUEUE; uint64_t nextTimeUs = EMPTY_QUEUE;
int counter = 0; int counter = 0;
@ -78,18 +80,18 @@ uint64_t EventQueue::getNextEventTime(uint64_t nowX) {
} }
if (current->momentX <= 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 * looks like we end up here after 'writeconfig' (which freezes the firmware) - we are late
* for the next scheduled event * for the next scheduled event
*/ */
uint64_t mock = nowX + lateDelay; uint64_t aBitInTheFuture = nowX + lateDelay;
if (mock < nextTimeUs) return aBitInTheFuture;
nextTimeUs = mock;
} else { } else {
if (current->momentX < nextTimeUs) return current->momentX;
nextTimeUs = current->momentX;
} }
} }
return nextTimeUs; return EMPTY_QUEUE;
} }
// static scheduling_s * longScheduling; // static scheduling_s * longScheduling;
@ -118,6 +120,12 @@ int EventQueue::executeAll(uint64_t now) {
executionCounter++; executionCounter++;
LL_DELETE(head, current); LL_DELETE(head, current);
LL_PREPEND(executionList, 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 #if EFI_UNIT_TEST

View File

@ -11,6 +11,9 @@
#ifndef EVENT_SCHEDULER_H_ #ifndef EVENT_SCHEDULER_H_
#define 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 EMPTY_QUEUE 0x0FFFFFFFFFFFFFFFLL
#define QUEUE_LENGTH_LIMIT 1000 #define QUEUE_LENGTH_LIMIT 1000
@ -43,7 +46,10 @@ class EventQueue {
public: public:
EventQueue(); 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); int executeAll(uint64_t now);
@ -56,6 +62,9 @@ public:
void assertListIsSorted(); void assertListIsSorted();
private: private:
bool checkIfPending(scheduling_s *scheduling); bool checkIfPending(scheduling_s *scheduling);
/**
* this list is sorted
*/
scheduling_s *head; scheduling_s *head;
uint64_t lateDelay; uint64_t lateDelay;
}; };

View File

@ -400,7 +400,7 @@ static void testRpmCalculator(void) {
// engine.rpmCalculator = &eth.rpmState; // engine.rpmCalculator = &eth.rpmState;
prepareTimingMap(PASS_ENGINE_PARAMETER_F); prepareTimingMap(PASS_ENGINE_PARAMETER_F);
assertEqualsM("queue size", 0, schedulingQueue.size()); assertEqualsM("queue size/0", 0, schedulingQueue.size());
debugSignalExecutor = true; debugSignalExecutor = true;
@ -415,10 +415,9 @@ static void testRpmCalculator(void) {
assertEqualsM("dwell offset", 14.0316, ilist->elements[0].dwellPosition.angleOffset); assertEqualsM("dwell offset", 14.0316, ilist->elements[0].dwellPosition.angleOffset);
assertEqualsM("index #2", 0, eth.triggerCentral.triggerState.getCurrentIndex()); 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); scheduling_s *ev1 = schedulingQueue.getForUnitText(0);
assertREquals((void*)ev1->callback, (void*)turnPinHigh); assertREquals((void*)ev1->callback, (void*)turnPinHigh);
assertREquals((void*)&enginePins.coils[3], ev1->param);
assertEqualsM("ev 1", 245000, ev1->momentX); assertEqualsM("ev 1", 245000, ev1->momentX);
assertEqualsM("ev 2", 245000, schedulingQueue.getForUnitText(1)->momentX); assertEqualsM("ev 2", 245000, schedulingQueue.getForUnitText(1)->momentX);