Moved delta list functions into the generic lists header.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14344 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2021-05-07 09:17:28 +00:00
parent 312b29e5b8
commit 4421ff5524
6 changed files with 177 additions and 141 deletions

View File

@ -98,10 +98,10 @@
/* Base kernel headers.*/
#include "chtypes.h"
#include "chearly.h"
#include "chlists.h"
#include "chalign.h"
#include "chdebug.h"
#include "chtime.h"
#include "chlists.h"
#include "chalign.h"
#include "chtrace.h"
#include "chport.h"
#include "chtm.h"

View File

@ -83,9 +83,24 @@ typedef struct ch_priority_queue ch_priority_queue_t;
* @note Link fields are void pointers in order to avoid aliasing issues.
*/
struct ch_priority_queue {
ch_priority_queue_t *next; /**< @brief Next in the list/queue. */
ch_priority_queue_t *next; /**< @brief Next in the queue. */
ch_priority_queue_t *prev; /**< @brief Previous in the queue. */
tprio_t prio;
tprio_t prio; /**< @brief Priority of this element. */
};
/**
* @brief Type of a generic bidirectional linked delta list
* header and element.
*/
typedef struct ch_delta_list ch_delta_list_t;
/**
* @brief Delta list element and header structure.
*/
struct ch_delta_list {
ch_delta_list_t *next; /**< @brief Next in the delta list. */
ch_delta_list_t *prev; /**< @brief Previous in the delta list. */
sysinterval_t delta; /**< @brief Time interval from previous.*/
};
/*===========================================================================*/
@ -401,6 +416,143 @@ static inline ch_priority_queue_t *ch_pqueue_insert_ahead(ch_priority_queue_t *p
return p;
}
/**
* @brief Delta list initialization.
*
* @param[out] dlp pointer to the delta list header
*
* @notapi
*/
static inline void ch_dlist_init(ch_delta_list_t *dlhp) {
dlhp->next = dlhp;
dlhp->prev = dlhp;
dlhp->delta = (sysinterval_t)-1;
}
/**
* @brief Evaluates to @p true if the specified delta list is empty.
*
* @param[in] dlhp pointer to the delta list header
* @return The status of the delta list.
*
* @notapi
*/
static inline bool ch_dlist_isempty(ch_delta_list_t *dlhp) {
return (bool)(dlhp == dlhp->next);
}
/**
* @brief Evaluates to @p true if the specified queue is not empty.
*
* @param[in] dlhp pointer to the delta list header
* @return The status of the delta list.
*
* @notapi
*/
static inline bool ch_dlist_notempty(ch_delta_list_t *dlhp) {
return (bool)(dlhp != dlhp->next);
}
/**
* @brief Last element in the delta list check.
*
* @param[in] dlhp pointer to the delta list header
* @param[in] dlp pointer to the delta list element
*
* @notapi
*/
static inline bool ch_dlist_islast(ch_delta_list_t *dlhp,
ch_delta_list_t *dlp) {
return (bool)(dlp->next == dlhp);
}
/**
* @brief Fist element in the delta list check.
*
* @param[in] dlhp pointer to the delta list header
* @param[in] dlp pointer to the delta list element
*
* @notapi
*/
static inline bool ch_dlist_isfirst(ch_delta_list_t *dlhp,
ch_delta_list_t *dlp) {
return (bool)(dlhp->next == dlp);
}
/**
* @brief Inserts an element after another header element.
*
* @param[in] dlhp pointer to the delta list header element
* @param[in] dlp element to be inserted after the header element
*
* @notapi
*/
static inline void ch_dlist_insert_after(ch_delta_list_t *dlhp,
ch_delta_list_t *dlp,
sysinterval_t delta) {
dlp->delta = delta;
dlp->prev = dlhp;
dlp->next = dlp->prev->next;
dlp->next->prev = dlp;
dlhp->next = dlp;
}
/**
* @brief Inserts an element before another header element.
*
* @param[in] dlhp pointer to the delta list header element
* @param[in] dlp element to be inserted before the header element
*
* @notapi
*/
static inline void ch_dlist_insert_before(ch_delta_list_t *dlhp,
ch_delta_list_t *dlp,
sysinterval_t delta) {
dlp->delta = delta;
dlp->next = dlhp;
dlp->prev = dlp->next->prev;
dlp->prev->next = dlp;
dlhp->prev = dlp;
}
/**
* @brief Dequeues an element from the delta list.
*
* @param[in] dlhp pointer to the delta list header
*
* @notapi
*/
static inline ch_delta_list_t *ch_dlist_remove_first(ch_delta_list_t *dlhp) {
ch_delta_list_t *dlp = dlhp->next;
dlhp->next = dlp->next;
dlhp->next->prev = dlhp;
return dlp;
}
/**
* @brief Dequeues an element from the delta list.
*
* @param[in] dlp pointer to the delta list element
*
* @notapi
*/
static inline ch_delta_list_t *ch_dlist_dequeue(ch_delta_list_t *dlp) {
dlp->prev->next = dlp->next;
dlp->next->prev = dlp->prev;
return dlp;
}
#endif /* CHLISTS_H */
/** @} */

View File

@ -59,29 +59,6 @@ typedef enum {
*/
typedef void (*vtfunc_t)(void *p);
/**
* @brief Type of a Virtual Timer structure.
*/
typedef struct ch_delta_list delta_list_t;
/**
* @brief Virtual Timer delta list element and header structure.
*/
struct ch_delta_list {
/**
* @brief Next timer in the list.
*/
delta_list_t *next;
/**
* @brief Previous timer in the list.
*/
delta_list_t *prev;
/**
* @brief Time delta before timeout.
*/
sysinterval_t delta;
};
/**
* @brief Type of a Virtual Timer.
*/
@ -89,7 +66,7 @@ typedef struct ch_virtual_timer {
/**
* @brief Delta list element.
*/
delta_list_t dlist;
ch_delta_list_t dlist;
/**
* @brief Timer callback function pointer.
*/
@ -114,7 +91,7 @@ typedef struct ch_virtual_timers_list {
/**
* @brief Delta list header.
*/
delta_list_t dlist;
ch_delta_list_t dlist;
#if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__)
/**
* @brief System Time counter.
@ -142,7 +119,7 @@ typedef struct ch_registry {
/**
* @brief Registry queue header.
*/
ch_queue_t queue;
ch_queue_t queue;
} registry_t;
/**

View File

@ -215,7 +215,7 @@ static inline bool chVTIsSystemTimeWithin(systime_t start, systime_t end) {
*/
static inline bool chVTGetTimersStateI(sysinterval_t *timep) {
virtual_timers_list_t *vtlp = &currcore->vtlist;
delta_list_t *dlp = &vtlp->dlist;
ch_delta_list_t *dlp = &vtlp->dlist;
chDbgCheckClassI();
@ -510,9 +510,7 @@ static inline void chVTResetTimeStamp(void) {
*/
static inline void __vt_object_init(virtual_timers_list_t *vtlp) {
vtlp->dlist.next = &vtlp->dlist;
vtlp->dlist.prev = &vtlp->dlist;
vtlp->dlist.delta = (sysinterval_t)-1;
ch_dlist_init(&vtlp->dlist);
#if CH_CFG_ST_TIMEDELTA == 0
vtlp->systime = (systime_t)0;
#else /* CH_CFG_ST_TIMEDELTA > 0 */

View File

@ -283,7 +283,7 @@ bool chSysIntegrityCheckI(unsigned testmask) {
/* Timers list integrity check.*/
if ((testmask & CH_INTEGRITY_VTLIST) != 0U) {
delta_list_t *dlp;
ch_delta_list_t *dlp;
/* Scanning the timers list forward.*/
n = (cnt_t)0;

View File

@ -48,45 +48,7 @@
/* Module local functions. */
/*===========================================================================*/
/**
* @brief List empty check.
*
* @param[in] dlhp pointer to the delta list header
*
* @notapi
*/
static inline bool is_vtlist_empty(delta_list_t *dlhp) {
return (bool)(dlhp == dlhp->next);
}
#if (CH_CFG_ST_TIMEDELTA > 0) || defined(__DOXYGEN__)
/**
* @brief Last timer in the list check.
*
* @param[in] dlhp pointer to the delta list header
* @param[in] dlp pointer to the delta list element
*
* @notapi
*/
static inline bool is_last_timer(delta_list_t *dlhp, delta_list_t *dlp) {
return (bool)(dlp->next == dlhp);
}
/**
* @brief Fist timer in the list check.
*
* @param[in] dlhp pointer to the delta list header
* @param[in] dlp pointer to the delta list element
*
* @notapi
*/
static inline bool is_first_timer(delta_list_t *dlhp, delta_list_t *dlp) {
return (bool)(dlhp->next == dlp);
}
/**
* @brief Timer check.
*
@ -95,64 +57,11 @@ static inline bool is_first_timer(delta_list_t *dlhp, delta_list_t *dlp) {
*
* @notapi
*/
static inline bool is_timer(delta_list_t *dlhp, delta_list_t *dlp) {
static inline bool is_timer(ch_delta_list_t *dlhp, ch_delta_list_t *dlp) {
return (bool)(dlp != dlhp);
}
/**
* @brief Dequeues an element from the delta list.
*
* @param[in] dlp pointer to the delta list element
*
* @notapi
*/
static delta_list_t *dlist_dequeue(delta_list_t *dlp) {
dlp->prev->next = dlp->next;
dlp->next->prev = dlp->prev;
return dlp;
}
/**
* @brief Dequeues an element from the delta list.
*
* @param[in] dlhp pointer to the delta list header
*
* @notapi
*/
static delta_list_t *dlist_remove_first(delta_list_t *dlhp) {
delta_list_t *dlp = dlhp->next;
dlhp->next = dlp->next;
dlhp->next->prev = dlhp;
return dlp;
}
static void dlist_insert_after(delta_list_t *dlhp,
delta_list_t *dlp,
sysinterval_t delta) {
dlp->delta = delta;
dlp->prev = dlhp;
dlp->next = dlp->prev->next;
dlp->next->prev = dlp;
dlhp->next = dlp;
}
static void dlist_insert_before(delta_list_t *dlhp,
delta_list_t *dlp,
sysinterval_t delta) {
dlp->delta = delta;
dlp->next = dlhp;
dlp->prev = dlp->next->prev;
dlp->prev->next = dlp;
dlhp->prev = dlp;
}
/**
* @brief Delta list compression.
*
@ -163,7 +72,7 @@ static void dlist_insert_before(delta_list_t *dlhp,
*/
static void vt_list_compress(virtual_timers_list_t *vtlp,
sysinterval_t deltanow) {
delta_list_t *dlp = vtlp->dlist.next;
ch_delta_list_t *dlp = vtlp->dlist.next;
vtlp->lasttime = chTimeAddX(vtlp->lasttime, deltanow);
@ -192,7 +101,7 @@ static void vt_enqueue(virtual_timers_list_t *vtlp,
virtual_timer_t *vtp,
systime_t now,
sysinterval_t delay) {
delta_list_t *dlp;
ch_delta_list_t *dlp;
sysinterval_t delta;
#if CH_CFG_ST_TIMEDELTA > 0
@ -206,12 +115,12 @@ static void vt_enqueue(virtual_timers_list_t *vtlp,
}
/* Special case where the timers list is empty.*/
if (is_vtlist_empty(&vtlp->dlist)) {
if (ch_dlist_isempty(&vtlp->dlist)) {
/* The delta list is empty, the current time becomes the new
delta list base time, the timer is inserted.*/
vtlp->lasttime = now;
dlist_insert_after(&vtlp->dlist, &vtp->dlist, delay);
ch_dlist_insert_after(&vtlp->dlist, &vtp->dlist, delay);
#if CH_CFG_INTERVALS_SIZE > CH_CFG_ST_RESOLUTION
/* The delta could be too large for the physical timer to handle.*/
@ -271,7 +180,7 @@ static void vt_enqueue(virtual_timers_list_t *vtlp,
}
/* The timer is inserted in the delta list.*/
dlist_insert_before(dlp, &vtp->dlist, delta);
ch_dlist_insert_before(dlp, &vtp->dlist, delta);
/* Calculate new delta for the following entry.*/
dlp->delta -= delta;
@ -401,10 +310,10 @@ void chVTDoResetI(virtual_timer_t *vtp) {
/* If the timer is not the first of the list then it is simply unlinked
else the operation is more complex.*/
if (!is_first_timer(&vtlp->dlist, &vtp->dlist)) {
if (!ch_dlist_isfirst(&vtlp->dlist, &vtp->dlist)) {
/* Removing the element from the delta list.*/
dlist_dequeue(&vtp->dlist);
ch_dlist_dequeue(&vtp->dlist);
/* Adding delta to the next element, if it is not the last one.*/
if (is_timer(&vtlp->dlist, vtp->dlist.next)) {
@ -418,11 +327,11 @@ void chVTDoResetI(virtual_timer_t *vtp) {
}
/* Removing the first timer from the list, marking it as not armed.*/
dlist_remove_first(&vtlp->dlist);
ch_dlist_remove_first(&vtlp->dlist);
vtp->dlist.next = NULL;
/* If the list become empty then the alarm timer is stopped and done.*/
if (is_vtlist_empty(&vtlp->dlist)) {
if (ch_dlist_isempty(&vtlp->dlist)) {
port_timer_stop_alarm();
return;
@ -474,7 +383,7 @@ void chVTDoResetI(virtual_timer_t *vtp) {
sysinterval_t chVTGetRemainingIntervalI(virtual_timer_t *vtp) {
virtual_timers_list_t *vtlp = &currcore->vtlist;
sysinterval_t deadline;
delta_list_t *dlp;
ch_delta_list_t *dlp;
chDbgCheckClassI();
@ -534,7 +443,7 @@ void chVTDoTickI(void) {
}
}
#else /* CH_CFG_ST_TIMEDELTA > 0 */
delta_list_t *dlp;
ch_delta_list_t *dlp;
sysinterval_t delta, nowdelta;
systime_t now;
@ -563,11 +472,11 @@ void chVTDoTickI(void) {
chDbgAssert((int)chTimeDiffX(vtlp->lasttime, now) >= 0, "back in time");
/* Removing the timer from the list, marking it as not armed.*/
dlist_dequeue(dlp);
ch_dlist_dequeue(dlp);
dlp->next = NULL;
/* If the list becomes empty then the timer is stopped.*/
if (is_vtlist_empty(&vtlp->dlist)) {
if (ch_dlist_isempty(&vtlp->dlist)) {
port_timer_stop_alarm();
}
@ -602,7 +511,7 @@ void chVTDoTickI(void) {
}
/* If the list is empty, nothing else to do.*/
if (is_vtlist_empty(&vtlp->dlist)) {
if (ch_dlist_isempty(&vtlp->dlist)) {
return;
}