2015-07-10 06:01:56 -07:00
|
|
|
/**
|
|
|
|
* @file event_queue.h
|
|
|
|
*
|
|
|
|
* @date Apr 17, 2014
|
2020-01-13 18:57:43 -08:00
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2020
|
2015-07-10 06:01:56 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "scheduler.h"
|
|
|
|
#include "utlist.h"
|
|
|
|
|
2020-01-20 22:40:11 -08:00
|
|
|
#pragma once
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* this is a large value which is expected to be larger than any real time
|
|
|
|
*/
|
|
|
|
#define EMPTY_QUEUE 0x0FFFFFFFFFFFFFFFLL
|
|
|
|
|
|
|
|
#define QUEUE_LENGTH_LIMIT 1000
|
|
|
|
|
2019-11-23 14:04:51 -08:00
|
|
|
// 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; \
|
|
|
|
} \
|
|
|
|
} \
|
2015-07-10 06:01:56 -07:00
|
|
|
return false;
|
2019-11-23 14:04:51 -08:00
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2016-01-25 20:01:36 -08:00
|
|
|
/**
|
|
|
|
* Execution sorted linked list
|
|
|
|
*/
|
2015-07-10 06:01:56 -07:00
|
|
|
class EventQueue {
|
|
|
|
public:
|
|
|
|
EventQueue();
|
|
|
|
|
|
|
|
/**
|
2016-01-25 20:01:36 -08:00
|
|
|
* O(size) - linear search in sorted linked list
|
2015-07-10 06:01:56 -07:00
|
|
|
*/
|
2020-01-06 21:41:18 -08:00
|
|
|
bool insertTask(scheduling_s *scheduling, efitime_t timeX, action_s action);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
int executeAll(efitime_t now);
|
|
|
|
|
2019-06-08 06:51:36 -07:00
|
|
|
efitime_t getNextEventTime(efitime_t nowUs) const;
|
2015-07-10 06:01:56 -07:00
|
|
|
void clear(void);
|
2019-06-08 06:51:36 -07:00
|
|
|
int size(void) const;
|
2019-12-02 21:20:47 -08:00
|
|
|
scheduling_s *getElementAtIndexForUnitText(int index);
|
2015-07-10 06:01:56 -07:00
|
|
|
void setLateDelay(int value);
|
|
|
|
scheduling_s * getHead();
|
2019-06-08 06:51:36 -07:00
|
|
|
void assertListIsSorted() const;
|
2015-07-10 06:01:56 -07:00
|
|
|
private:
|
|
|
|
bool checkIfPending(scheduling_s *scheduling);
|
|
|
|
/**
|
|
|
|
* this list is sorted
|
|
|
|
*/
|
|
|
|
scheduling_s *head;
|
|
|
|
efitime_t lateDelay;
|
|
|
|
};
|
|
|
|
|