explicit list field to simplify code navigation
This commit is contained in:
parent
ee674dc979
commit
aa4967383a
|
@ -91,7 +91,7 @@ public:
|
|||
/**
|
||||
* Ignition scheduler maintains a linked list of all pending ignition events.
|
||||
*/
|
||||
IgnitionEvent *next = nullptr;
|
||||
IgnitionEvent *nextIgnitionEvent = nullptr;
|
||||
/**
|
||||
* Sequential number of currently processed spark event
|
||||
* @see globalSparkIdCounter
|
||||
|
|
|
@ -30,7 +30,7 @@ EventQueue::EventQueue() {
|
|||
}
|
||||
|
||||
bool EventQueue::checkIfPending(scheduling_s *scheduling) {
|
||||
return assertNotInList<scheduling_s>(head, scheduling);
|
||||
assertNotInListMethodBody(scheduling_s, head, scheduling, nextScheduling_s);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -63,7 +63,7 @@ bool EventQueue::insertTask(scheduling_s *scheduling, efitime_t timeX, schfunc_t
|
|||
|
||||
if (head == NULL || timeX < head->momentX) {
|
||||
// here we insert into head of the linked list
|
||||
LL_PREPEND(head, scheduling);
|
||||
LL_PREPEND2(head, scheduling, nextScheduling_s);
|
||||
#if EFI_UNIT_TEST
|
||||
assertListIsSorted();
|
||||
#endif /* EFI_UNIT_TEST */
|
||||
|
@ -71,12 +71,12 @@ bool EventQueue::insertTask(scheduling_s *scheduling, efitime_t timeX, schfunc_t
|
|||
} else {
|
||||
// here we know we are not in the head of the list, let's find the position - linear search
|
||||
scheduling_s *insertPosition = head;
|
||||
while (insertPosition->next != NULL && insertPosition->next->momentX < timeX) {
|
||||
insertPosition = insertPosition->next;
|
||||
while (insertPosition->nextScheduling_s != NULL && insertPosition->nextScheduling_s->momentX < timeX) {
|
||||
insertPosition = insertPosition->nextScheduling_s;
|
||||
}
|
||||
|
||||
scheduling->next = insertPosition->next;
|
||||
insertPosition->next = scheduling;
|
||||
scheduling->nextScheduling_s = insertPosition->nextScheduling_s;
|
||||
insertPosition->nextScheduling_s = scheduling;
|
||||
#if EFI_UNIT_TEST
|
||||
assertListIsSorted();
|
||||
#endif /* EFI_UNIT_TEST */
|
||||
|
@ -132,7 +132,7 @@ int EventQueue::executeAll(efitime_t now) {
|
|||
int listIterationCounter = 0;
|
||||
int executionCounter = 0;
|
||||
// we need safe iteration because we are removing elements inside the loop
|
||||
LL_FOREACH_SAFE(head, current, tmp)
|
||||
LL_FOREACH_SAFE2(head, current, tmp, nextScheduling_s)
|
||||
{
|
||||
efiAssert(CUSTOM_ERR_ASSERT, current->callback != NULL, "callback==null1", 0);
|
||||
if (++listIterationCounter > QUEUE_LENGTH_LIMIT) {
|
||||
|
@ -143,14 +143,14 @@ int EventQueue::executeAll(efitime_t now) {
|
|||
executionCounter++;
|
||||
efiAssert(CUSTOM_ERR_ASSERT, head == current, "removing from head", -1);
|
||||
//LL_DELETE(head, current);
|
||||
head = head->next;
|
||||
head = head->nextScheduling_s;
|
||||
if (executionList == NULL) {
|
||||
lastInExecutionList = executionList = current;
|
||||
} else {
|
||||
lastInExecutionList->next = current;
|
||||
lastInExecutionList->nextScheduling_s = current;
|
||||
lastInExecutionList = current;
|
||||
}
|
||||
current->next = nullptr;
|
||||
current->nextScheduling_s = nullptr;
|
||||
} else {
|
||||
/**
|
||||
* The list is sorted. Once we find one action in the future, all the remaining ones
|
||||
|
@ -167,7 +167,7 @@ int EventQueue::executeAll(efitime_t now) {
|
|||
* we need safe iteration here because 'callback' might change change 'current->next'
|
||||
* while re-inserting it into the queue from within the callback
|
||||
*/
|
||||
LL_FOREACH_SAFE(executionList, current, tmp)
|
||||
LL_FOREACH_SAFE2(executionList, current, tmp, nextScheduling_s)
|
||||
{
|
||||
efiAssert(CUSTOM_ERR_ASSERT, current->callback != NULL, "callback==null2", 0);
|
||||
uint32_t before = getTimeNowLowerNt();
|
||||
|
@ -198,16 +198,16 @@ int EventQueue::executeAll(efitime_t now) {
|
|||
int EventQueue::size(void) const {
|
||||
scheduling_s *tmp;
|
||||
int result;
|
||||
LL_COUNT(head, tmp, result);
|
||||
LL_COUNT2(head, tmp, result, nextScheduling_s);
|
||||
return result;
|
||||
}
|
||||
|
||||
#if EFI_UNIT_TEST
|
||||
void EventQueue::assertListIsSorted() const {
|
||||
scheduling_s *current = head;
|
||||
while (current != NULL && current->next != NULL) {
|
||||
efiAssertVoid(CUSTOM_ERR_6623, current->momentX <= current->next->momentX, "list order");
|
||||
current = current->next;
|
||||
while (current != NULL && current->nextScheduling_s != NULL) {
|
||||
efiAssertVoid(CUSTOM_ERR_6623, current->momentX <= current->nextScheduling_s->momentX, "list order");
|
||||
current = current->nextScheduling_s;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -223,7 +223,7 @@ scheduling_s * EventQueue::getHead() {
|
|||
scheduling_s *EventQueue::getForUnitText(int index) {
|
||||
scheduling_s * current;
|
||||
|
||||
LL_FOREACH(head, current)
|
||||
LL_FOREACH2(head, current, nextScheduling_s)
|
||||
{
|
||||
if (index == 0)
|
||||
return current;
|
||||
|
|
|
@ -18,29 +18,28 @@
|
|||
|
||||
#define QUEUE_LENGTH_LIMIT 1000
|
||||
|
||||
template<typename T>
|
||||
bool assertNotInList(T *head, T*element) {
|
||||
// this code is just to validate state, no functional load
|
||||
T * current;
|
||||
int counter = 0;
|
||||
LL_FOREACH(head, current)
|
||||
{
|
||||
if (++counter > QUEUE_LENGTH_LIMIT) {
|
||||
firmwareError(CUSTOM_ERR_LOOPED_QUEUE, "Looped queue?");
|
||||
return false;
|
||||
}
|
||||
if (current == element) {
|
||||
/**
|
||||
* for example, this might happen in case of sudden RPM change if event
|
||||
* was not scheduled by angle but was scheduled by time. In case of scheduling
|
||||
* by time with slow RPM the whole next fast revolution might be within the wait period
|
||||
*/
|
||||
warning(CUSTOM_RE_ADDING_INTO_EXECUTION_QUEUE, "re-adding element into event_queue");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// templates do not accept field names so we use a macro here
|
||||
#define assertNotInListMethodBody(T, head, element, field) \
|
||||
/* this code is just to validate state, no functional load*/ \
|
||||
T * current; \
|
||||
int counter = 0; \
|
||||
LL_FOREACH2(head, current, field) { \
|
||||
if (++counter > QUEUE_LENGTH_LIMIT) { \
|
||||
firmwareError(CUSTOM_ERR_LOOPED_QUEUE, "Looped queue?"); \
|
||||
return false; \
|
||||
} \
|
||||
if (current == element) { \
|
||||
/** \
|
||||
* for example, this might happen in case of sudden RPM change if event \
|
||||
* was not scheduled by angle but was scheduled by time. In case of scheduling \
|
||||
* by time with slow RPM the whole next fast revolution might be within the wait period \
|
||||
*/ \
|
||||
warning(CUSTOM_RE_ADDING_INTO_EXECUTION_QUEUE, "re-adding element into event_queue"); \
|
||||
return true; \
|
||||
} \
|
||||
} \
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execution sorted linked list
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
/**
|
||||
* Scheduler implementation uses a sorted linked list of these scheduling records.
|
||||
*/
|
||||
scheduling_s *next = nullptr;
|
||||
scheduling_s *nextScheduling_s = nullptr;
|
||||
|
||||
schfunc_t callback = nullptr;
|
||||
void *param = nullptr;
|
||||
|
|
|
@ -215,6 +215,10 @@ void turnSparkPinHigh(IgnitionEvent *event) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool assertNotInIgnitionList(IgnitionEvent *head, IgnitionEvent *element) {
|
||||
assertNotInListMethodBody(IgnitionEvent, head, element, nextIgnitionEvent)
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void handleSparkEvent(bool limitedSpark, uint32_t trgEventIndex, IgnitionEvent *iEvent,
|
||||
int rpm DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
|
||||
|
@ -315,7 +319,7 @@ static ALWAYS_INLINE void handleSparkEvent(bool limitedSpark, uint32_t trgEventI
|
|||
/**
|
||||
* Spark should be scheduled in relation to some future trigger event, this way we get better firing precision
|
||||
*/
|
||||
bool isPending = assertNotInList<IgnitionEvent>(ENGINE(ignitionEventsHead), iEvent);
|
||||
bool isPending = assertNotInIgnitionList(ENGINE(ignitionEventsHead), iEvent);
|
||||
if (isPending) {
|
||||
#if SPARK_EXTREME_LOGGING
|
||||
scheduleMsg(logger, "not adding to queue sparkDown ind=%d %d %s %d", trgEventIndex, getRevolutionCounter(), iEvent->getOutputForLoggins()->name, (int)getTimeNowUs());
|
||||
|
@ -323,7 +327,7 @@ static ALWAYS_INLINE void handleSparkEvent(bool limitedSpark, uint32_t trgEventI
|
|||
return;
|
||||
}
|
||||
|
||||
LL_APPEND(ENGINE(ignitionEventsHead), iEvent);
|
||||
LL_APPEND2(ENGINE(ignitionEventsHead), iEvent, nextIgnitionEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -383,11 +387,11 @@ static ALWAYS_INLINE void prepareIgnitionSchedule(DECLARE_ENGINE_PARAMETER_SIGNA
|
|||
static void scheduleAllSparkEventsUntilNextTriggerTooth(uint32_t trgEventIndex DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||
IgnitionEvent *current, *tmp;
|
||||
|
||||
LL_FOREACH_SAFE(ENGINE(ignitionEventsHead), current, tmp)
|
||||
LL_FOREACH_SAFE2(ENGINE(ignitionEventsHead), current, tmp, nextIgnitionEvent)
|
||||
{
|
||||
if (current->sparkPosition.triggerEventIndex == trgEventIndex) {
|
||||
// time to fire a spark which was scheduled previously
|
||||
LL_DELETE(ENGINE(ignitionEventsHead), current);
|
||||
LL_DELETE2(ENGINE(ignitionEventsHead), current, nextIgnitionEvent);
|
||||
|
||||
scheduling_s * sDown = ¤t->signalTimerDown;
|
||||
|
||||
|
|
|
@ -108,9 +108,9 @@ TEST(misc, testSignalExecutor) {
|
|||
|
||||
ASSERT_EQ(4, eq.size());
|
||||
ASSERT_EQ(10, eq.getHead()->momentX);
|
||||
ASSERT_EQ(10, eq.getHead()->next->momentX);
|
||||
ASSERT_EQ(11, eq.getHead()->next->next->momentX);
|
||||
ASSERT_EQ(12, eq.getHead()->next->next->next->momentX);
|
||||
ASSERT_EQ(10, eq.getHead()->nextScheduling_s->momentX);
|
||||
ASSERT_EQ(11, eq.getHead()->nextScheduling_s->nextScheduling_s->momentX);
|
||||
ASSERT_EQ(12, eq.getHead()->nextScheduling_s->nextScheduling_s->nextScheduling_s->momentX);
|
||||
|
||||
callbackCounter = 0;
|
||||
eq.executeAll(10);
|
||||
|
|
Loading…
Reference in New Issue