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.*/ /* Base kernel headers.*/
#include "chtypes.h" #include "chtypes.h"
#include "chearly.h" #include "chearly.h"
#include "chlists.h"
#include "chalign.h"
#include "chdebug.h" #include "chdebug.h"
#include "chtime.h" #include "chtime.h"
#include "chlists.h"
#include "chalign.h"
#include "chtrace.h" #include "chtrace.h"
#include "chport.h" #include "chport.h"
#include "chtm.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. * @note Link fields are void pointers in order to avoid aliasing issues.
*/ */
struct ch_priority_queue { 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. */ 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; 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 */ #endif /* CHLISTS_H */
/** @} */ /** @} */

View File

@ -59,29 +59,6 @@ typedef enum {
*/ */
typedef void (*vtfunc_t)(void *p); 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. * @brief Type of a Virtual Timer.
*/ */
@ -89,7 +66,7 @@ typedef struct ch_virtual_timer {
/** /**
* @brief Delta list element. * @brief Delta list element.
*/ */
delta_list_t dlist; ch_delta_list_t dlist;
/** /**
* @brief Timer callback function pointer. * @brief Timer callback function pointer.
*/ */
@ -114,7 +91,7 @@ typedef struct ch_virtual_timers_list {
/** /**
* @brief Delta list header. * @brief Delta list header.
*/ */
delta_list_t dlist; ch_delta_list_t dlist;
#if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__) #if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__)
/** /**
* @brief System Time counter. * @brief System Time counter.
@ -142,7 +119,7 @@ typedef struct ch_registry {
/** /**
* @brief Registry queue header. * @brief Registry queue header.
*/ */
ch_queue_t queue; ch_queue_t queue;
} registry_t; } 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) { static inline bool chVTGetTimersStateI(sysinterval_t *timep) {
virtual_timers_list_t *vtlp = &currcore->vtlist; virtual_timers_list_t *vtlp = &currcore->vtlist;
delta_list_t *dlp = &vtlp->dlist; ch_delta_list_t *dlp = &vtlp->dlist;
chDbgCheckClassI(); chDbgCheckClassI();
@ -510,9 +510,7 @@ static inline void chVTResetTimeStamp(void) {
*/ */
static inline void __vt_object_init(virtual_timers_list_t *vtlp) { static inline void __vt_object_init(virtual_timers_list_t *vtlp) {
vtlp->dlist.next = &vtlp->dlist; ch_dlist_init(&vtlp->dlist);
vtlp->dlist.prev = &vtlp->dlist;
vtlp->dlist.delta = (sysinterval_t)-1;
#if CH_CFG_ST_TIMEDELTA == 0 #if CH_CFG_ST_TIMEDELTA == 0
vtlp->systime = (systime_t)0; vtlp->systime = (systime_t)0;
#else /* CH_CFG_ST_TIMEDELTA > 0 */ #else /* CH_CFG_ST_TIMEDELTA > 0 */

View File

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

View File

@ -48,45 +48,7 @@
/* Module local functions. */ /* 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__) #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. * @brief Timer check.
* *
@ -95,64 +57,11 @@ static inline bool is_first_timer(delta_list_t *dlhp, delta_list_t *dlp) {
* *
* @notapi * @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); 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. * @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, static void vt_list_compress(virtual_timers_list_t *vtlp,
sysinterval_t deltanow) { sysinterval_t deltanow) {
delta_list_t *dlp = vtlp->dlist.next; ch_delta_list_t *dlp = vtlp->dlist.next;
vtlp->lasttime = chTimeAddX(vtlp->lasttime, deltanow); vtlp->lasttime = chTimeAddX(vtlp->lasttime, deltanow);
@ -192,7 +101,7 @@ static void vt_enqueue(virtual_timers_list_t *vtlp,
virtual_timer_t *vtp, virtual_timer_t *vtp,
systime_t now, systime_t now,
sysinterval_t delay) { sysinterval_t delay) {
delta_list_t *dlp; ch_delta_list_t *dlp;
sysinterval_t delta; sysinterval_t delta;
#if CH_CFG_ST_TIMEDELTA > 0 #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.*/ /* 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 /* The delta list is empty, the current time becomes the new
delta list base time, the timer is inserted.*/ delta list base time, the timer is inserted.*/
vtlp->lasttime = now; 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 #if CH_CFG_INTERVALS_SIZE > CH_CFG_ST_RESOLUTION
/* The delta could be too large for the physical timer to handle.*/ /* 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.*/ /* 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.*/ /* Calculate new delta for the following entry.*/
dlp->delta -= delta; 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 /* If the timer is not the first of the list then it is simply unlinked
else the operation is more complex.*/ 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.*/ /* 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.*/ /* Adding delta to the next element, if it is not the last one.*/
if (is_timer(&vtlp->dlist, vtp->dlist.next)) { 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.*/ /* 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; vtp->dlist.next = NULL;
/* If the list become empty then the alarm timer is stopped and done.*/ /* 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(); port_timer_stop_alarm();
return; return;
@ -474,7 +383,7 @@ void chVTDoResetI(virtual_timer_t *vtp) {
sysinterval_t chVTGetRemainingIntervalI(virtual_timer_t *vtp) { sysinterval_t chVTGetRemainingIntervalI(virtual_timer_t *vtp) {
virtual_timers_list_t *vtlp = &currcore->vtlist; virtual_timers_list_t *vtlp = &currcore->vtlist;
sysinterval_t deadline; sysinterval_t deadline;
delta_list_t *dlp; ch_delta_list_t *dlp;
chDbgCheckClassI(); chDbgCheckClassI();
@ -534,7 +443,7 @@ void chVTDoTickI(void) {
} }
} }
#else /* CH_CFG_ST_TIMEDELTA > 0 */ #else /* CH_CFG_ST_TIMEDELTA > 0 */
delta_list_t *dlp; ch_delta_list_t *dlp;
sysinterval_t delta, nowdelta; sysinterval_t delta, nowdelta;
systime_t now; systime_t now;
@ -563,11 +472,11 @@ void chVTDoTickI(void) {
chDbgAssert((int)chTimeDiffX(vtlp->lasttime, now) >= 0, "back in time"); chDbgAssert((int)chTimeDiffX(vtlp->lasttime, now) >= 0, "back in time");
/* Removing the timer from the list, marking it as not armed.*/ /* Removing the timer from the list, marking it as not armed.*/
dlist_dequeue(dlp); ch_dlist_dequeue(dlp);
dlp->next = NULL; dlp->next = NULL;
/* If the list becomes empty then the timer is stopped.*/ /* 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(); port_timer_stop_alarm();
} }
@ -602,7 +511,7 @@ void chVTDoTickI(void) {
} }
/* If the list is empty, nothing else to do.*/ /* If the list is empty, nothing else to do.*/
if (is_vtlist_empty(&vtlp->dlist)) { if (ch_dlist_isempty(&vtlp->dlist)) {
return; return;
} }