explicit list field to simplify code navigation

This commit is contained in:
rusefi 2019-11-23 17:04:51 -05:00
parent ee674dc979
commit aa4967383a
6 changed files with 50 additions and 47 deletions

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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 = &current->signalTimerDown;

View File

@ -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);