Initial fix for bug #1138. To be completed by running all regression and quality checks.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13958 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2020-12-17 14:32:54 +00:00
parent 22a2569793
commit 817fe8f3de
24 changed files with 288 additions and 506 deletions

View File

@ -82,8 +82,8 @@ typedef struct {
(msg_t *)(buffer), \
(size_t)0, \
false, \
_THREADS_QUEUE_DATA(name.qw), \
_THREADS_QUEUE_DATA(name.qr), \
__THREADS_QUEUE_DATA(name.qw), \
__THREADS_QUEUE_DATA(name.qr), \
}
/**

View File

@ -95,7 +95,7 @@ typedef struct {
* @param[in] align required memory alignment
* @param[in] provider memory provider function for the memory pool
*/
#define _MEMORYPOOL_DATA(name, size, align, provider) \
#define __MEMORYPOOL_DATA(name, size, align, provider) \
{NULL, size, align, provider}
/**
@ -110,7 +110,7 @@ typedef struct {
* if the pool is not allowed to grow automatically
*/
#define MEMORYPOOL_DECL(name, size, align, provider) \
memory_pool_t name = _MEMORYPOOL_DATA(name, size, align, provider)
memory_pool_t name = __MEMORYPOOL_DATA(name, size, align, provider)
#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
/**
@ -122,9 +122,9 @@ typedef struct {
* @param[in] size size of the memory pool contained objects
* @param[in] align required memory alignment
*/
#define _GUARDEDMEMORYPOOL_DATA(name, size, align) { \
_SEMAPHORE_DATA(name.sem, (cnt_t)0), \
_MEMORYPOOL_DATA(NULL, size, align, NULL) \
#define __GUARDEDMEMORYPOOL_DATA(name, size, align) { \
__SEMAPHORE_DATA(name.sem, (cnt_t)0), \
__MEMORYPOOL_DATA(NULL, size, align, NULL) \
}
/**
@ -137,7 +137,7 @@ typedef struct {
* @param[in] align required memory alignment
*/
#define GUARDEDMEMORYPOOL_DECL(name, size, align) \
guarded_memory_pool_t name = _GUARDEDMEMORYPOOL_DATA(name, size, align)
guarded_memory_pool_t name = __GUARDEDMEMORYPOOL_DATA(name, size, align)
#endif /* CH_CFG_USE_SEMAPHORES == TRUE */
/*===========================================================================*/

View File

@ -85,7 +85,7 @@ typedef struct {
* @param[in] size number of @p uint8_t elements in the buffer array
*/
#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
#define _PIPE_DATA(name, buffer, size) { \
#define __PIPE_DATA(name, buffer, size) { \
(uint8_t *)(buffer), \
(uint8_t *)(buffer) + size, \
(uint8_t *)(buffer), \
@ -94,9 +94,9 @@ typedef struct {
false, \
NULL, \
NULL, \
_MUTEX_DATA(name.cmtx), \
_MUTEX_DATA(name.wmtx), \
_MUTEX_DATA(name.rmtx), \
__MUTEX_DATA(name.cmtx), \
__MUTEX_DATA(name.wmtx), \
__MUTEX_DATA(name.rmtx), \
}
#else /* CH_CFG_USE_MUTEXES == FALSE */
#define _PIPE_DATA(name, buffer, size) { \
@ -108,9 +108,9 @@ typedef struct {
false, \
NULL, \
NULL, \
_SEMAPHORE_DATA(name.csem, (cnt_t)1), \
_SEMAPHORE_DATA(name.wsem, (cnt_t)1), \
_SEMAPHORE_DATA(name.rsem, (cnt_t)1), \
__SEMAPHORE_DATA(name.csem, (cnt_t)1), \
__SEMAPHORE_DATA(name.wsem, (cnt_t)1), \
__SEMAPHORE_DATA(name.rsem, (cnt_t)1), \
}
#endif /* CH_CFG_USE_MUTEXES == FALSE */
@ -124,7 +124,7 @@ typedef struct {
* @param[in] size number of @p uint8_t elements in the buffer array
*/
#define PIPE_DECL(name, buffer, size) \
pipe_t name = _PIPE_DATA(name, buffer, size)
pipe_t name = __PIPE_DATA(name, buffer, size)
/*===========================================================================*/
/* External declarations. */

View File

@ -97,6 +97,7 @@
/* Base kernel headers.*/
#include "chtypes.h"
#include "chearly.h"
#include "chlists.h"
#include "chalign.h"
#include "chdebug.h"
#include "chtime.h"

View File

@ -57,7 +57,7 @@
* @brief condition_variable_t structure.
*/
typedef struct condition_variable {
threads_queue_t queue; /**< @brief Condition variable
ch_queue_t queue; /**< @brief Condition variable
threads queue. */
} condition_variable_t;
@ -72,7 +72,7 @@ typedef struct condition_variable {
*
* @param[in] name the name of the condition variable
*/
#define _CONDVAR_DATA(name) {_THREADS_QUEUE_DATA(name.queue)}
#define __CONDVAR_DATA(name) {__CH_QUEUE_DATA(name.queue)}
/**
* @brief Static condition variable initializer.
@ -81,7 +81,7 @@ typedef struct condition_variable {
*
* @param[in] name the name of the condition variable
*/
#define CONDVAR_DECL(name) condition_variable_t name = _CONDVAR_DATA(name)
#define CONDVAR_DECL(name) condition_variable_t name = __CONDVAR_DATA(name)
/*===========================================================================*/
/* External declarations. */

View File

@ -72,16 +72,12 @@ struct ch_queue {
};
/**
* @extends ch_queue_t
*
* @brief Type of a generic priority-ordered bidirectional linked list
* header and element.
*/
typedef struct ch_priority_queue ch_priority_queue_t;
/**
* @extends ch_queue_t
*
* @brief Structure representing a generic priority-ordered bidirectional
* linked list header and element.
* @note Link fields are void pointers in order to avoid aliasing issues.

View File

@ -168,7 +168,7 @@ static inline bool chMsgIsPendingI(thread_t *tp) {
chDbgCheckClassI();
return (bool)(tp->msgqueue.next != (thread_t *)&tp->msgqueue);
return (bool)(tp->msgqueue.next != &tp->msgqueue);
}
/**

View File

@ -55,7 +55,7 @@ typedef struct ch_mutex mutex_t;
* @brief Mutex structure.
*/
struct ch_mutex {
threads_queue_t queue; /**< @brief Queue of the threads sleeping
ch_queue_t queue; /**< @brief Queue of the threads sleeping
on this mutex. */
thread_t *owner; /**< @brief Owner @p thread_t pointer or
@p NULL. */
@ -78,9 +78,9 @@ struct ch_mutex {
* @param[in] name the name of the mutex variable
*/
#if (CH_CFG_USE_MUTEXES_RECURSIVE == TRUE) || defined(__DOXYGEN__)
#define _MUTEX_DATA(name) {_THREADS_QUEUE_DATA(name.queue), NULL, NULL, 0}
#define __MUTEX_DATA(name) {__CH_QUEUE_DATA(name.queue), NULL, NULL, 0}
#else
#define _MUTEX_DATA(name) {_THREADS_QUEUE_DATA(name.queue), NULL, NULL}
#define __MUTEX_DATA(name) {__CH_QUEUE_DATA(name.queue), NULL, NULL}
#endif
/**
@ -90,7 +90,7 @@ struct ch_mutex {
*
* @param[in] name the name of the mutex variable
*/
#define MUTEX_DECL(name) mutex_t name = _MUTEX_DATA(name)
#define MUTEX_DECL(name) mutex_t name = __MUTEX_DATA(name)
/*===========================================================================*/
/* External declarations. */
@ -129,7 +129,7 @@ static inline bool chMtxQueueNotEmptyS(mutex_t *mp) {
chDbgCheckClassS();
return queue_notempty(&mp->queue);
return ch_queue_notempty(&mp->queue);
}
/**

View File

@ -50,24 +50,29 @@
typedef void (*vtfunc_t)(void *p);
/**
* @extends virtual_timers_list_t
*
* @brief Type of a Virtual Timer structure.
*/
typedef struct ch_virtual_timer virtual_timer_t;
typedef struct ch_delta_list delta_list_t;
/**
* @brief Virtual Timer descriptor structure.
* @brief Virtual Timer delta list element and header structure.
*/
struct ch_virtual_timer {
virtual_timer_t *next; /**< @brief Next timer in the list. */
virtual_timer_t *prev; /**< @brief Previous timer in the list. */
struct ch_delta_list {
delta_list_t *next; /**< @brief Next timer in the list. */
delta_list_t *prev; /**< @brief Previous timer in the list. */
sysinterval_t delta; /**< @brief Time delta before timeout. */
};
/**
* @brief Type of a Virtual Timer.
*/
typedef struct ch_virtual_timer {
delta_list_t dlist; /**< @brief Delta list element. */
vtfunc_t func; /**< @brief Timer callback function
pointer. */
void *par; /**< @brief Timer callback function
parameter. */
};
} virtual_timer_t;
/**
* @brief Type of virtual timers list header.
@ -76,11 +81,7 @@ struct ch_virtual_timer {
* timer is often used in the code.
*/
typedef struct ch_virtual_timers_list {
virtual_timer_t *next; /**< @brief Next timer in the delta
list. */
virtual_timer_t *prev; /**< @brief Last timer in the delta
list. */
sysinterval_t delta; /**< @brief Must be initialized to -1. */
delta_list_t dlist; /**< @brief Delta list header. */
#if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__)
volatile systime_t systime; /**< @brief System Time counter. */
#endif
@ -102,21 +103,10 @@ typedef struct ch_virtual_timers_list {
typedef thread_t * thread_reference_t;
/**
* @brief Type of a generic threads single link list, it works like a stack.
*/
typedef struct ch_threads_list {
thread_t *next; /**< @brief Next in the list/queue. */
} threads_list_t;
/**
* @extends threads_list_t
*
* @brief Type of a generic threads bidirectional linked list header and
* element.
* @brief Type of a threads queue.
*/
typedef struct ch_threads_queue {
thread_t *next; /**< @brief Next in the list/queue. */
thread_t *prev; /**< @brief Previous in the queue. */
ch_queue_t queue; /**< @brief Threads queue header. */
} threads_queue_t;
/**
@ -126,7 +116,10 @@ typedef struct ch_threads_queue {
* by shrinking this structure.
*/
struct ch_thread {
threads_queue_t queue; /**< @brief Threads queue header. */
union {
ch_list_t list; /**< @brief Threads list header. */
ch_queue_t queue; /**< @brief Threads queue header. */
} hdr;
tprio_t prio; /**< @brief Thread priority. */
#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
thread_t *newer; /**< @brief Newer registry element. */
@ -250,13 +243,13 @@ struct ch_thread {
/**
* @brief Termination waiting list.
*/
threads_list_t waiting;
ch_list_t waiting;
#endif
#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
/**
* @brief Messages queue.
*/
threads_queue_t msgqueue;
ch_queue_t msgqueue;
#endif
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
/**
@ -300,7 +293,7 @@ struct ch_thread {
* @brief Type of a ready list header.
*/
typedef struct ch_ready_list {
threads_queue_t queue; /**< @brief Threads queue. */
ch_queue_t queue; /**< @brief Threads queue. */
tprio_t prio; /**< @brief This field must be
initialized to zero. */
#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)

View File

@ -127,7 +127,7 @@
*
* @notapi
*/
#define firstprio(rlp) ((rlp)->next->prio)
#define firstprio(rlp) (((thread_t *)(rlp)->next)->prio)
/**
* @brief Current thread pointer get macro.
@ -180,144 +180,19 @@ extern "C" {
/* Module inline functions. */
/*===========================================================================*/
/**
* @brief Threads list initialization.
*
* @param[in] tlp pointer to the threads list object
*
* @notapi
*/
static inline void list_init(threads_list_t *tlp) {
tlp->next = (thread_t *)tlp;
}
/**
* @brief Evaluates to @p true if the specified threads list is empty.
*
* @param[in] tlp pointer to the threads list object
* @return The status of the list.
*
* @notapi
*/
static inline bool list_isempty(threads_list_t *tlp) {
return (bool)(tlp->next == (thread_t *)tlp);
}
/**
* @brief Evaluates to @p true if the specified threads list is not empty.
*
* @param[in] tlp pointer to the threads list object
* @return The status of the list.
*
* @notapi
*/
static inline bool list_notempty(threads_list_t *tlp) {
return (bool)(tlp->next != (thread_t *)tlp);
}
/**
* @brief Threads queue initialization.
*
* @param[in] tqp pointer to the threads queue object
*
* @notapi
*/
static inline void queue_init(threads_queue_t *tqp) {
tqp->next = (thread_t *)tqp;
tqp->prev = (thread_t *)tqp;
}
/**
* @brief Evaluates to @p true if the specified threads queue is empty.
*
* @param[in] tqp pointer to the threads queue object
* @return The status of the queue.
*
* @notapi
*/
static inline bool queue_isempty(const threads_queue_t *tqp) {
return (bool)(tqp->next == (const thread_t *)tqp);
}
/**
* @brief Evaluates to @p true if the specified threads queue is not empty.
*
* @param[in] tqp pointer to the threads queue object
* @return The status of the queue.
*
* @notapi
*/
static inline bool queue_notempty(const threads_queue_t *tqp) {
return (bool)(tqp->next != (const thread_t *)tqp);
}
/* If the performance code path has been chosen then all the following
functions are inlined into the various kernel modules.*/
#if CH_CFG_OPTIMIZE_SPEED == TRUE
static inline void list_insert(thread_t *tp, threads_list_t *tlp) {
tp->queue.next = tlp->next;
tlp->next = tp;
}
static inline thread_t *list_remove(threads_list_t *tlp) {
thread_t *tp = tlp->next;
tlp->next = tp->queue.next;
return tp;
}
static inline void queue_prio_insert(thread_t *tp, threads_queue_t *tqp) {
static inline void queue_prio_insert(thread_t *tp, ch_queue_t *tqp) {
thread_t *cp = (thread_t *)tqp;
do {
cp = cp->queue.next;
cp = (thread_t *)cp->hdr.queue.next;
} while ((cp != (thread_t *)tqp) && (cp->prio >= tp->prio));
tp->queue.next = cp;
tp->queue.prev = cp->queue.prev;
tp->queue.prev->queue.next = tp;
cp->queue.prev = tp;
}
static inline void queue_insert(thread_t *tp, threads_queue_t *tqp) {
tp->queue.next = (thread_t *)tqp;
tp->queue.prev = tqp->prev;
tp->queue.prev->queue.next = tp;
tqp->prev = tp;
}
static inline thread_t *queue_fifo_remove(threads_queue_t *tqp) {
thread_t *tp = tqp->next;
tqp->next = tp->queue.next;
tqp->next->queue.prev = (thread_t *)tqp;
return tp;
}
static inline thread_t *queue_lifo_remove(threads_queue_t *tqp) {
thread_t *tp = tqp->prev;
tqp->prev = tp->queue.prev;
tqp->prev->queue.next = (thread_t *)tqp;
return tp;
}
static inline thread_t *queue_dequeue(thread_t *tp) {
tp->queue.prev->queue.next = tp->queue.next;
tp->queue.next->queue.prev = tp->queue.prev;
return tp;
tp->hdr.queue.next = (ch_queue_t *)cp;
tp->hdr.queue.prev = cp->hdr.queue.prev;
tp->hdr.queue.prev->next = (ch_queue_t *)tp;
cp->hdr.queue.prev = (ch_queue_t *)tp;
}
#endif /* CH_CFG_OPTIMIZE_SPEED == TRUE */

View File

@ -50,7 +50,7 @@
* @brief Semaphore structure.
*/
typedef struct ch_semaphore {
threads_queue_t queue; /**< @brief Queue of the threads sleeping
ch_queue_t queue; /**< @brief Queue of the threads sleeping
on this semaphore. */
cnt_t cnt; /**< @brief The semaphore counter. */
} semaphore_t;
@ -68,7 +68,7 @@ typedef struct ch_semaphore {
* @param[in] n the counter initial value, this value must be
* non-negative
*/
#define _SEMAPHORE_DATA(name, n) {_THREADS_QUEUE_DATA(name.queue), n}
#define __SEMAPHORE_DATA(name, n) {__CH_QUEUE_DATA(name.queue), n}
/**
* @brief Static semaphore initializer.
@ -79,7 +79,7 @@ typedef struct ch_semaphore {
* @param[in] n the counter initial value, this value must be
* non-negative
*/
#define SEMAPHORE_DECL(name, n) semaphore_t name = _SEMAPHORE_DATA(name, n)
#define SEMAPHORE_DECL(name, n) semaphore_t name = __SEMAPHORE_DATA(name, n)
/*===========================================================================*/
/* External declarations. */

View File

@ -384,8 +384,8 @@ static inline void chSysUnlock(void) {
in a critical section not followed by a chSchRescheduleS(), this means
that the current thread has a lower priority than the next thread in
the ready list.*/
chDbgAssert((currcore->rlist.queue.next == (thread_t *)&currcore->rlist.queue) ||
(currcore->rlist.current->prio >= currcore->rlist.queue.next->prio),
chDbgAssert((currcore->rlist.queue.next == &currcore->rlist.queue) ||
(currcore->rlist.current->prio >= ((thread_t *)currcore->rlist.queue.next)->prio),
"priority order violation");
port_unlock();
@ -477,7 +477,7 @@ static inline void chSysUnconditionalUnlock(void) {
*/
static inline thread_t *chSysGetIdleThreadX(void) {
return currcore->rlist.queue.prev;
return (thread_t *)currcore->rlist.queue.prev;
}
#endif /* CH_CFG_NO_IDLE_THREAD == FALSE */

View File

@ -95,7 +95,7 @@ typedef struct {
*
* @param[in] name the name of the threads queue variable
*/
#define _THREADS_QUEUE_DATA(name) {(thread_t *)&name, (thread_t *)&name}
#define __THREADS_QUEUE_DATA(name) {__CH_QUEUE_DATA(name)}
/**
* @brief Static threads queue object initializer.
@ -104,8 +104,8 @@ typedef struct {
*
* @param[in] name the name of the threads queue variable
*/
#define _THREADS_QUEUE_DECL(name) \
threads_queue_t name = _THREADS_QUEUE_DATA(name)
#define THREADS_QUEUE_DECL(name) \
threads_queue_t name = __THREADS_QUEUE_DATA(name)
/** @} */
/**
@ -394,7 +394,7 @@ static inline void chThdSleepS(sysinterval_t ticks) {
*/
static inline void chThdQueueObjectInit(threads_queue_t *tqp) {
queue_init(tqp);
ch_queue_init(&tqp->queue);
}
/**
@ -411,7 +411,7 @@ static inline bool chThdQueueIsEmptyI(threads_queue_t *tqp) {
chDbgCheckClassI();
return queue_isempty(tqp);
return ch_queue_isempty(&tqp->queue);
}
/**
@ -428,9 +428,9 @@ static inline bool chThdQueueIsEmptyI(threads_queue_t *tqp) {
static inline void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg) {
thread_t *tp;
chDbgAssert(queue_notempty(tqp), "empty queue");
chDbgAssert(ch_queue_notempty(&tqp->queue), "empty queue");
tp = queue_fifo_remove(tqp);
tp = (thread_t *)ch_queue_fifo_remove(&tqp->queue);
chDbgAssert(tp->state == CH_STATE_QUEUED, "invalid state");

View File

@ -212,10 +212,11 @@ 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;
chDbgCheckClassI();
if (vtlp == (virtual_timers_list_t *)vtlp->next) {
if (dlp == dlp->next) {
return false;
}
@ -223,7 +224,7 @@ static inline bool chVTGetTimersStateI(sysinterval_t *timep) {
#if CH_CFG_ST_TIMEDELTA == 0
*timep = vtlp->next->delta;
#else
*timep = (vtlp->next->delta + (sysinterval_t)CH_CFG_ST_TIMEDELTA) -
*timep = (dlp->next->delta + (sysinterval_t)CH_CFG_ST_TIMEDELTA) -
chTimeDiffX(vtlp->lasttime, chVTGetSystemTimeX());
#endif
}
@ -416,9 +417,9 @@ static inline void chVTResetTimeStamp(void) {
*/
static inline void __vt_object_init(virtual_timers_list_t *vtlp) {
vtlp->next = (virtual_timer_t *)vtlp;
vtlp->prev = (virtual_timer_t *)vtlp;
vtlp->delta = (sysinterval_t)-1;
vtlp->dlist.next = &vtlp->dlist;
vtlp->dlist.prev = &vtlp->dlist;
vtlp->dlist.delta = (sysinterval_t)-1;
#if CH_CFG_ST_TIMEDELTA == 0
vtlp->systime = (systime_t)0;
#else /* CH_CFG_ST_TIMEDELTA > 0 */

View File

@ -76,7 +76,7 @@ void chCondObjectInit(condition_variable_t *cp) {
chDbgCheck(cp != NULL);
queue_init(&cp->queue);
ch_queue_init(&cp->queue);
}
/**
@ -91,8 +91,8 @@ void chCondSignal(condition_variable_t *cp) {
chDbgCheck(cp != NULL);
chSysLock();
if (queue_notempty(&cp->queue)) {
chSchWakeupS(queue_fifo_remove(&cp->queue), MSG_OK);
if (ch_queue_notempty(&cp->queue)) {
chSchWakeupS((thread_t *)ch_queue_fifo_remove(&cp->queue), MSG_OK);
}
chSysUnlock();
}
@ -113,8 +113,8 @@ void chCondSignalI(condition_variable_t *cp) {
chDbgCheckClassI();
chDbgCheck(cp != NULL);
if (queue_notempty(&cp->queue)) {
thread_t *tp = queue_fifo_remove(&cp->queue);
if (ch_queue_notempty(&cp->queue)) {
thread_t *tp = (thread_t *)ch_queue_fifo_remove(&cp->queue);
tp->u.rdymsg = MSG_OK;
(void) chSchReadyI(tp);
}
@ -154,8 +154,8 @@ void chCondBroadcastI(condition_variable_t *cp) {
/* Empties the condition variable queue and inserts all the threads into the
ready list in FIFO order. The wakeup message is set to @p MSG_RESET in
order to make a chCondBroadcast() detectable from a chCondSignal().*/
while (queue_notempty(&cp->queue)) {
chSchReadyI(queue_fifo_remove(&cp->queue))->u.rdymsg = MSG_RESET;
while (ch_queue_notempty(&cp->queue)) {
chSchReadyI((thread_t *)ch_queue_fifo_remove(&cp->queue))->u.rdymsg = MSG_RESET;
}
}

View File

@ -66,7 +66,7 @@
#if CH_CFG_USE_MESSAGES_PRIORITY == TRUE
#define msg_insert(tp, qp) queue_prio_insert(tp, qp)
#else
#define msg_insert(tp, qp) queue_insert(tp, qp)
#define msg_insert(tp, qp) ch_queue_insert((ch_queue_t *)tp, qp)
#endif
/*===========================================================================*/
@ -127,7 +127,7 @@ thread_t *chMsgWaitS(void) {
if (!chMsgIsPendingI(currtp)) {
chSchGoSleepS(CH_STATE_WTMSG);
}
tp = queue_fifo_remove(&currtp->msgqueue);
tp = (thread_t *)ch_queue_fifo_remove(&currtp->msgqueue);
tp->state = CH_STATE_SNDMSG;
return tp;
@ -166,7 +166,7 @@ thread_t *chMsgWaitTimeoutS(sysinterval_t timeout) {
return NULL;
}
}
tp = queue_fifo_remove(&currtp->msgqueue);
tp = (thread_t *)ch_queue_fifo_remove(&currtp->msgqueue);
tp->state = CH_STATE_SNDMSG;
return tp;
@ -194,7 +194,7 @@ thread_t *chMsgPollS(void) {
thread_t *tp = NULL;
if (chMsgIsPendingI(currtp)) {
tp = queue_fifo_remove(&currtp->msgqueue);
tp = (thread_t *)ch_queue_fifo_remove(&currtp->msgqueue);
tp->state = CH_STATE_SNDMSG;
}

View File

@ -104,7 +104,7 @@ void chMtxObjectInit(mutex_t *mp) {
chDbgCheck(mp != NULL);
queue_init(&mp->queue);
ch_queue_init(&mp->queue);
mp->owner = NULL;
#if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE
mp->cnt = (cnt_t)0;
@ -170,7 +170,8 @@ void chMtxLockS(mutex_t *mp) {
switch (tp->state) {
case CH_STATE_WTMTX:
/* Re-enqueues the mutex owner with its new priority.*/
queue_prio_insert(queue_dequeue(tp), &tp->u.wtmtxp->queue);
queue_prio_insert((thread_t *)ch_queue_dequeue(&tp->hdr.queue),
&tp->u.wtmtxp->queue);
tp = tp->u.wtmtxp->owner;
/*lint -e{9042} [16.1] Continues the while.*/
continue;
@ -190,7 +191,8 @@ void chMtxLockS(mutex_t *mp) {
case CH_STATE_SNDMSGQ:
#endif
/* Re-enqueues tp with its new priority on the queue.*/
queue_prio_insert(queue_dequeue(tp), &tp->u.wtmtxp->queue);
queue_prio_insert((thread_t *)ch_queue_dequeue(&tp->hdr.queue),
&tp->u.wtmtxp->queue);
break;
#endif
case CH_STATE_READY:
@ -199,7 +201,7 @@ void chMtxLockS(mutex_t *mp) {
tp->state = CH_STATE_CURRENT;
#endif
/* Re-enqueues tp with its new priority on the ready list.*/
(void) chSchReadyI(queue_dequeue(tp));
(void) chSchReadyI((thread_t *)ch_queue_dequeue(&tp->hdr.queue));
break;
default:
/* Nothing to do for other states.*/
@ -357,8 +359,8 @@ void chMtxUnlock(mutex_t *mp) {
greater priority than the current thread base priority then the
final priority will have at least that priority.*/
if (chMtxQueueNotEmptyS(lmp) &&
(lmp->queue.next->prio > newprio)) {
newprio = lmp->queue.next->prio;
(((thread_t *)lmp->queue.next)->prio > newprio)) {
newprio = ((thread_t *)lmp->queue.next)->prio;
}
lmp = lmp->next;
}
@ -372,7 +374,7 @@ void chMtxUnlock(mutex_t *mp) {
#if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE
mp->cnt = (cnt_t)1;
#endif
tp = queue_fifo_remove(&mp->queue);
tp = (thread_t *)ch_queue_fifo_remove(&mp->queue);
mp->owner = tp;
mp->next = tp->mtxlist;
tp->mtxlist = mp;
@ -443,8 +445,8 @@ void chMtxUnlockS(mutex_t *mp) {
greater priority than the current thread base priority then the
final priority will have at least that priority.*/
if (chMtxQueueNotEmptyS(lmp) &&
(lmp->queue.next->prio > newprio)) {
newprio = lmp->queue.next->prio;
(((thread_t *)lmp->queue.next)->prio > newprio)) {
newprio = ((thread_t *)lmp->queue.next)->prio;
}
lmp = lmp->next;
}
@ -458,7 +460,7 @@ void chMtxUnlockS(mutex_t *mp) {
#if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE
mp->cnt = (cnt_t)1;
#endif
tp = queue_fifo_remove(&mp->queue);
tp = (thread_t *)ch_queue_fifo_remove(&mp->queue);
mp->owner = tp;
mp->next = tp->mtxlist;
tp->mtxlist = mp;
@ -497,7 +499,7 @@ void chMtxUnlockAllS(void) {
#if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE
mp->cnt = (cnt_t)1;
#endif
tp = queue_fifo_remove(&mp->queue);
tp = (thread_t *)ch_queue_fifo_remove(&mp->queue);
mp->owner = tp;
mp->next = tp->mtxlist;
tp->mtxlist = mp;

View File

@ -91,7 +91,7 @@ static void __idle_thread(void *p) {
* @notapi
*/
static thread_t *__sch_ready_behind(os_instance_t *oip, thread_t *tp) {
thread_t *cp;
ch_queue_t *cqp, *tqp;
chDbgAssert((tp->state != CH_STATE_READY) &&
(tp->state != CH_STATE_FINAL),
@ -102,16 +102,17 @@ static thread_t *__sch_ready_behind(os_instance_t *oip, thread_t *tp) {
/* Scanning ready list.*/
tp->state = CH_STATE_READY;
cp = (thread_t *)&oip->rlist.queue;
tqp = &tp->hdr.queue;
cqp = &oip->rlist.queue;
do {
cp = cp->queue.next;
} while (cp->prio >= tp->prio);
cqp = cqp->next;
} while (((thread_t *)cqp)->prio >= tp->prio);
/* Insertion on prev.*/
tp->queue.next = cp;
tp->queue.prev = cp->queue.prev;
tp->queue.prev->queue.next = tp;
cp->queue.prev = tp;
tqp->next = cqp;
tqp->prev = cqp->prev;
tqp->prev->next = &tp->hdr.queue;
cqp->prev = tqp;
return tp;
}
@ -134,7 +135,7 @@ static thread_t *__sch_ready_behind(os_instance_t *oip, thread_t *tp) {
* @notapi
*/
static thread_t *__sch_ready_ahead(os_instance_t *oip, thread_t *tp) {
thread_t *cp;
ch_queue_t *cqp, *tqp;
chDbgAssert((tp->state != CH_STATE_READY) &&
(tp->state != CH_STATE_FINAL),
@ -145,16 +146,17 @@ static thread_t *__sch_ready_ahead(os_instance_t *oip, thread_t *tp) {
/* Scanning ready list.*/
tp->state = CH_STATE_READY;
cp = (thread_t *)&oip->rlist.queue;
tqp = &tp->hdr.queue;
cqp = &oip->rlist.queue;
do {
cp = cp->queue.next;
} while (cp->prio > tp->prio);
cqp = cqp->next;
} while (((thread_t *)cqp)->prio > tp->prio);
/* Insertion on prev.*/
tp->queue.next = cp;
tp->queue.prev = cp->queue.prev;
tp->queue.prev->queue.next = tp;
cp->queue.prev = tp;
tqp->next = cqp;
tqp->prev = cqp->prev;
tqp->prev->next = tqp;
cqp->prev = tqp;
return tp;
}
@ -176,7 +178,7 @@ static void __sch_reschedule_behind(os_instance_t *oip) {
thread_t *ntp;
/* Picks the first thread from the ready queue and makes it current.*/
ntp = queue_fifo_remove(&oip->rlist.queue);
ntp = (thread_t *)ch_queue_fifo_remove(&oip->rlist.queue);
ntp->state = CH_STATE_CURRENT;
__sch_set_currthread(oip, ntp);
@ -213,7 +215,7 @@ static void __sch_reschedule_ahead(os_instance_t *oip) {
thread_t *ntp;
/* Picks the first thread from the ready queue and makes it current.*/
ntp = queue_fifo_remove(&oip->rlist.queue);
ntp = (thread_t *)ch_queue_fifo_remove(&oip->rlist.queue);
ntp->state = CH_STATE_CURRENT;
__sch_set_currthread(oip, ntp);
@ -256,7 +258,7 @@ static void __sch_wakeup(void *p) {
case CH_STATE_WTCOND:
#endif
/* States requiring dequeuing.*/
(void) queue_dequeue(tp);
(void) ch_queue_dequeue(&tp->hdr.queue);
break;
default:
/* Any other state, nothing to do.*/
@ -297,109 +299,6 @@ void queue_prio_insert(thread_t *tp, threads_queue_t *tqp) {
tp->queue.prev->queue.next = tp;
cp->queue.prev = tp;
}
/**
* @brief Inserts a thread into a queue.
*
* @param[in] tp the pointer to the thread to be inserted in the list
* @param[in] tqp the pointer to the threads list header
*
* @notapi
*/
void queue_insert(thread_t *tp, threads_queue_t *tqp) {
tp->queue.next = (thread_t *)tqp;
tp->queue.prev = tqp->prev;
tp->queue.prev->queue.next = tp;
tqp->prev = tp;
}
/**
* @brief Removes the first-out thread from a queue and returns it.
* @note If the queue is priority ordered then this function returns the
* thread with the highest priority.
*
* @param[in] tqp the pointer to the threads list header
* @return The removed thread pointer.
*
* @notapi
*/
thread_t *queue_fifo_remove(threads_queue_t *tqp) {
thread_t *tp = tqp->next;
tqp->next = tp->queue.next;
tqp->next->queue.prev = (thread_t *)tqp;
return tp;
}
/**
* @brief Removes the last-out thread from a queue and returns it.
* @note If the queue is priority ordered then this function returns the
* thread with the lowest priority.
*
* @param[in] tqp the pointer to the threads list header
* @return The removed thread pointer.
*
* @notapi
*/
thread_t *queue_lifo_remove(threads_queue_t *tqp) {
thread_t *tp = tqp->prev;
tqp->prev = tp->queue.prev;
tqp->prev->queue.next = (thread_t *)tqp;
return tp;
}
/**
* @brief Removes a thread from a queue and returns it.
* @details The thread is removed from the queue regardless of its relative
* position and regardless the used insertion method.
*
* @param[in] tp the pointer to the thread to be removed from the queue
* @return The removed thread pointer.
*
* @notapi
*/
thread_t *queue_dequeue(thread_t *tp) {
tp->queue.prev->queue.next = tp->queue.next;
tp->queue.next->queue.prev = tp->queue.prev;
return tp;
}
/**
* @brief Pushes a thread_t on top of a stack list.
*
* @param[in] tp the pointer to the thread to be inserted in the list
* @param[in] tlp the pointer to the threads list header
*
* @notapi
*/
void list_insert(thread_t *tp, threads_list_t *tlp) {
tp->queue.next = tlp->next;
tlp->next = tp;
}
/**
* @brief Pops a thread from the top of a stack list and returns it.
* @pre The list must be non-empty before calling this function.
*
* @param[in] tlp the pointer to the threads list header
* @return The removed thread pointer.
*
* @notapi
*/
thread_t *list_remove(threads_list_t *tlp) {
thread_t *tp = tlp->next;
tlp->next = tp->queue.next;
return tp;
}
#endif /* CH_CFG_OPTIMIZE_SPEED */
/**
@ -418,7 +317,7 @@ void chSchObjectInit(os_instance_t *oip,
port_init(oip);
/* Ready list initialization.*/
queue_init(&oip->rlist.queue);
ch_queue_init(&oip->rlist.queue);
oip->rlist.prio = NOPRIO;
/* Registry initialization.*/
@ -544,7 +443,7 @@ void chSchGoSleepS(tstate_t newstate) {
#endif
/* Next thread in ready list becomes current.*/
ntp = queue_fifo_remove(&oip->rlist.queue);
ntp = (thread_t *)ch_queue_fifo_remove(&oip->rlist.queue);
ntp->state = CH_STATE_CURRENT;
__sch_set_currthread(oip, ntp);
@ -622,8 +521,8 @@ void chSchWakeupS(thread_t *ntp, msg_t msg) {
chDbgCheckClassS();
chDbgAssert((oip->rlist.queue.next == (thread_t *)&oip->rlist.queue) ||
(oip->rlist.current->prio >= oip->rlist.queue.next->prio),
chDbgAssert((oip->rlist.queue.next == &oip->rlist.queue) ||
(oip->rlist.current->prio >= ((thread_t *)oip->rlist.queue.next)->prio),
"priority order violation");
/* Storing the message to be retrieved by the target thread when it will
@ -728,7 +627,7 @@ void chSchDoPreemption(void) {
thread_t *ntp;
/* Picks the first thread from the ready queue and makes it current.*/
ntp = queue_fifo_remove(&oip->rlist.queue);
ntp = (thread_t *)ch_queue_fifo_remove(&oip->rlist.queue);
ntp->state = CH_STATE_CURRENT;
__sch_set_currthread(oip, ntp);
@ -834,7 +733,7 @@ thread_t *chSchSelectFirstI(void) {
thread_t *ntp;
/* Picks the first thread from the ready queue and makes it current.*/
ntp = queue_fifo_remove(&oip->rlist.queue);
ntp = (thread_t *)ch_queue_fifo_remove(&oip->rlist.queue);
ntp->state = CH_STATE_CURRENT;
__sch_set_currthread(oip, ntp);

View File

@ -78,7 +78,7 @@
#if CH_CFG_USE_SEMAPHORES_PRIORITY == TRUE
#define sem_insert(tp, qp) queue_prio_insert(tp, qp)
#else
#define sem_insert(tp, qp) queue_insert(tp, qp)
#define sem_insert(tp, qp) ch_queue_insert((ch_queue_t *)tp, qp)
#endif
/*===========================================================================*/
@ -98,7 +98,7 @@ void chSemObjectInit(semaphore_t *sp, cnt_t n) {
chDbgCheck((sp != NULL) && (n >= (cnt_t)0));
queue_init(&sp->queue);
ch_queue_init(&sp->queue);
sp->cnt = n;
}
@ -144,13 +144,13 @@ void chSemResetWithMessageI(semaphore_t *sp, cnt_t n, msg_t msg) {
chDbgCheckClassI();
chDbgCheck((sp != NULL) && (n >= (cnt_t)0));
chDbgAssert(((sp->cnt >= (cnt_t)0) && queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && queue_notempty(&sp->queue)),
chDbgAssert(((sp->cnt >= (cnt_t)0) && ch_queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && ch_queue_notempty(&sp->queue)),
"inconsistent semaphore");
sp->cnt = n;
while (queue_notempty(&sp->queue)) {
chSchReadyI(queue_lifo_remove(&sp->queue))->u.rdymsg = msg;
while (ch_queue_notempty(&sp->queue)) {
chSchReadyI((thread_t *)ch_queue_lifo_remove(&sp->queue))->u.rdymsg = msg;
}
}
@ -192,8 +192,8 @@ msg_t chSemWaitS(semaphore_t *sp) {
chDbgCheckClassS();
chDbgCheck(sp != NULL);
chDbgAssert(((sp->cnt >= (cnt_t)0) && queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && queue_notempty(&sp->queue)),
chDbgAssert(((sp->cnt >= (cnt_t)0) && ch_queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && ch_queue_notempty(&sp->queue)),
"inconsistent semaphore");
if (--sp->cnt < (cnt_t)0) {
@ -260,8 +260,8 @@ msg_t chSemWaitTimeoutS(semaphore_t *sp, sysinterval_t timeout) {
chDbgCheckClassS();
chDbgCheck(sp != NULL);
chDbgAssert(((sp->cnt >= (cnt_t)0) && queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && queue_notempty(&sp->queue)),
chDbgAssert(((sp->cnt >= (cnt_t)0) && ch_queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && ch_queue_notempty(&sp->queue)),
"inconsistent semaphore");
if (--sp->cnt < (cnt_t)0) {
@ -292,11 +292,11 @@ void chSemSignal(semaphore_t *sp) {
chDbgCheck(sp != NULL);
chSysLock();
chDbgAssert(((sp->cnt >= (cnt_t)0) && queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && queue_notempty(&sp->queue)),
chDbgAssert(((sp->cnt >= (cnt_t)0) && ch_queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && ch_queue_notempty(&sp->queue)),
"inconsistent semaphore");
if (++sp->cnt <= (cnt_t)0) {
chSchWakeupS(queue_fifo_remove(&sp->queue), MSG_OK);
chSchWakeupS((thread_t *)ch_queue_fifo_remove(&sp->queue), MSG_OK);
}
chSysUnlock();
}
@ -316,14 +316,14 @@ void chSemSignalI(semaphore_t *sp) {
chDbgCheckClassI();
chDbgCheck(sp != NULL);
chDbgAssert(((sp->cnt >= (cnt_t)0) && queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && queue_notempty(&sp->queue)),
chDbgAssert(((sp->cnt >= (cnt_t)0) && ch_queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && ch_queue_notempty(&sp->queue)),
"inconsistent semaphore");
if (++sp->cnt <= (cnt_t)0) {
/* Note, it is done this way in order to allow a tail call on
chSchReadyI().*/
thread_t *tp = queue_fifo_remove(&sp->queue);
thread_t *tp = (thread_t *)ch_queue_fifo_remove(&sp->queue);
tp->u.rdymsg = MSG_OK;
(void) chSchReadyI(tp);
}
@ -346,13 +346,13 @@ void chSemAddCounterI(semaphore_t *sp, cnt_t n) {
chDbgCheckClassI();
chDbgCheck((sp != NULL) && (n > (cnt_t)0));
chDbgAssert(((sp->cnt >= (cnt_t)0) && queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && queue_notempty(&sp->queue)),
chDbgAssert(((sp->cnt >= (cnt_t)0) && ch_queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && ch_queue_notempty(&sp->queue)),
"inconsistent semaphore");
while (n > (cnt_t)0) {
if (++sp->cnt <= (cnt_t)0) {
chSchReadyI(queue_fifo_remove(&sp->queue))->u.rdymsg = MSG_OK;
chSchReadyI((thread_t *)ch_queue_fifo_remove(&sp->queue))->u.rdymsg = MSG_OK;
}
n--;
}
@ -377,14 +377,14 @@ msg_t chSemSignalWait(semaphore_t *sps, semaphore_t *spw) {
chDbgCheck((sps != NULL) && (spw != NULL));
chSysLock();
chDbgAssert(((sps->cnt >= (cnt_t)0) && queue_isempty(&sps->queue)) ||
((sps->cnt < (cnt_t)0) && queue_notempty(&sps->queue)),
chDbgAssert(((sps->cnt >= (cnt_t)0) && ch_queue_isempty(&sps->queue)) ||
((sps->cnt < (cnt_t)0) && ch_queue_notempty(&sps->queue)),
"inconsistent semaphore");
chDbgAssert(((spw->cnt >= (cnt_t)0) && queue_isempty(&spw->queue)) ||
((spw->cnt < (cnt_t)0) && queue_notempty(&spw->queue)),
chDbgAssert(((spw->cnt >= (cnt_t)0) && ch_queue_isempty(&spw->queue)) ||
((spw->cnt < (cnt_t)0) && ch_queue_notempty(&spw->queue)),
"inconsistent semaphore");
if (++sps->cnt <= (cnt_t)0) {
chSchReadyI(queue_fifo_remove(&sps->queue))->u.rdymsg = MSG_OK;
chSchReadyI((thread_t *)ch_queue_fifo_remove(&sps->queue))->u.rdymsg = MSG_OK;
}
if (--spw->cnt < (cnt_t)0) {
thread_t *currtp = chThdGetSelfX();

View File

@ -172,21 +172,21 @@ bool chSysIntegrityCheckI(unsigned testmask) {
/* Ready List integrity check.*/
if ((testmask & CH_INTEGRITY_RLIST) != 0U) {
thread_t *tp;
ch_queue_t *qp;
/* Scanning the ready list forward.*/
n = (cnt_t)0;
tp = oip->rlist.queue.next;
while (tp != (thread_t *)&oip->rlist.queue) {
qp = oip->rlist.queue.next;
while (qp != &oip->rlist.queue) {
n++;
tp = tp->queue.next;
qp = qp->next;
}
/* Scanning the ready list backward.*/
tp = oip->rlist.queue.prev;
while (tp != (thread_t *)&oip->rlist.queue) {
qp = oip->rlist.queue.prev;
while (qp != &oip->rlist.queue) {
n--;
tp = tp->queue.prev;
qp = qp->prev;
}
/* The number of elements must match.*/
@ -197,21 +197,21 @@ bool chSysIntegrityCheckI(unsigned testmask) {
/* Timers list integrity check.*/
if ((testmask & CH_INTEGRITY_VTLIST) != 0U) {
virtual_timer_t * vtp;
delta_list_t *dlp;
/* Scanning the timers list forward.*/
n = (cnt_t)0;
vtp = oip->vtlist.next;
while (vtp != (virtual_timer_t *)&oip->vtlist) {
dlp = oip->vtlist.dlist.next;
while (dlp != &oip->vtlist.dlist) {
n++;
vtp = vtp->next;
dlp = dlp->next;
}
/* Scanning the timers list backward.*/
vtp = oip->vtlist.prev;
while (vtp != (virtual_timer_t *)&oip->vtlist) {
dlp = oip->vtlist.dlist.prev;
while (dlp != &oip->vtlist.dlist) {
n--;
vtp = vtp->prev;
dlp = dlp->prev;
}
/* The number of elements must match.*/

View File

@ -118,10 +118,10 @@ thread_t *__thd_object_init(os_instance_t *oip,
(void)name;
#endif
#if CH_CFG_USE_WAITEXIT == TRUE
list_init(&tp->waiting);
ch_list_init(&tp->waiting);
#endif
#if CH_CFG_USE_MESSAGES == TRUE
queue_init(&tp->msgqueue);
ch_queue_init(&tp->msgqueue);
#endif
#if CH_DBG_STATISTICS == TRUE
chTMObjectInit(&tp->stats);
@ -515,8 +515,8 @@ void chThdExitS(msg_t msg) {
#if CH_CFG_USE_WAITEXIT == TRUE
/* Waking up any waiting thread.*/
while (list_notempty(&currtp->waiting)) {
(void) chSchReadyI(list_remove(&currtp->waiting));
while (ch_list_notempty(&currtp->waiting)) {
(void) chSchReadyI((thread_t *)ch_list_pop(&currtp->waiting));
}
#endif
@ -575,7 +575,7 @@ msg_t chThdWait(thread_t *tp) {
#endif
if (tp->state != CH_STATE_FINAL) {
list_insert(currtp, &tp->waiting);
ch_list_push(&currtp->hdr.list, &tp->waiting);
chSchGoSleepS(CH_STATE_WTEXIT);
}
msg = tp->u.exitcode;
@ -876,7 +876,7 @@ msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout) {
return MSG_TIMEOUT;
}
queue_insert(currtp, tqp);
ch_queue_insert((ch_queue_t *)currtp, &tqp->queue);
return chSchGoSleepTimeoutS(CH_STATE_QUEUED, timeout);
}
@ -892,7 +892,7 @@ msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout) {
*/
void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg) {
if (queue_notempty(tqp)) {
if (ch_queue_notempty(&tqp->queue)) {
chThdDoDequeueNextI(tqp, msg);
}
}
@ -907,7 +907,7 @@ void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg) {
*/
void chThdDequeueAllI(threads_queue_t *tqp, msg_t msg) {
while (queue_notempty(tqp)) {
while (ch_queue_notempty(&tqp->queue)) {
chThdDoDequeueNextI(tqp, msg);
}
}

View File

@ -32,45 +32,6 @@
/* Module local definitions. */
/*===========================================================================*/
/**
* @brief List empty check.
*
* @param[in] vtlp pointer to the list header
*
* @notapi
*/
#define is_vtlist_empty(vtlp) ((vtlp) == (virtual_timers_list_t *)(vtlp)->next)
/**
* @brief Last timer in the list check.
*
* @param[in] vtlp pointer to the list header
* @param[in] vtp pointer to the timer header
*
* @notapi
*/
#define is_last_timer(vtlp, vtp) ((vtp)->next == (virtual_timer_t *)(vtlp))
/**
* @brief Fist timer in the list check.
*
* @param[in] vtlp pointer to the list header
* @param[in] vtp pointer to the timer header
*
* @notapi
*/
#define is_first_timer(vtlp, vtp) ((vtlp)->next == (vtp))
/**
* @brief Timer check.
*
* @param[in] vtlp pointer to the list header
* @param[in] vtp pointer to the timer header
*
* @notapi
*/
#define is_timer(vtlp, vtp) ((vtp) != (virtual_timer_t *)(vtlp))
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/
@ -87,6 +48,57 @@
/* 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);
}
/**
* @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.
*
* @param[in] dlhp pointer to the delta list header
* @param[in] dlp pointer to the delta list element
*
* @notapi
*/
static inline bool is_timer(delta_list_t *dlhp, delta_list_t *dlp) {
return (bool)(dlp != dlhp);
}
#if (CH_CFG_ST_TIMEDELTA > 0) || defined(__DOXYGEN__)
/**
* @brief Delta list compression.
@ -98,21 +110,21 @@
*/
static void vt_list_compress(virtual_timers_list_t *vtlp,
sysinterval_t deltanow) {
virtual_timer_t *vtp = vtlp->next;
delta_list_t *dlp = vtlp->dlist.next;
/* The loop is bounded because the delta list header has the delta field
set to (sysinterval_t)-1 which is larger than all deltas.*/
while (vtp->delta < deltanow) {
deltanow -= vtp->delta;
vtp->delta = (sysinterval_t)0;
vtp = vtp->next;
while (dlp->delta < deltanow) {
deltanow -= dlp->delta;
dlp->delta = (sysinterval_t)0;
dlp = dlp->next;
}
vtlp->lasttime = vtlp->lasttime + deltanow;
/* Adjusting next timer in the list, if any.*/
if (is_timer(vtlp, vtp)) {
vtp->delta -= deltanow;
if (is_timer(&vtlp->dlist, dlp)) {
dlp->delta -= deltanow;
}
}
#endif
@ -146,7 +158,7 @@ static void vt_list_compress(virtual_timers_list_t *vtlp,
void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay,
vtfunc_t vtfunc, void *par) {
virtual_timers_list_t *vtlp = &currcore->vtlist;
virtual_timer_t *p;
delta_list_t *dlp;
sysinterval_t delta;
chDbgCheckClassI();
@ -167,16 +179,16 @@ void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay,
}
/* Special case where the timers list is empty.*/
if (is_vtlist_empty(vtlp)) {
if (is_vtlist_empty(&vtlp->dlist)) {
/* The delta list is empty, the current time becomes the new
delta list base time, the timer is inserted.*/
vtlp->lasttime = now;
vtlp->next = vtp;
vtlp->prev = vtp;
vtp->next = (virtual_timer_t *)vtlp;
vtp->prev = (virtual_timer_t *)vtlp;
vtp->delta = delay;
vtlp->dlist.next = &vtp->dlist;
vtlp->dlist.prev = &vtp->dlist;
vtp->dlist.next = &vtlp->dlist;
vtp->dlist.prev = &vtlp->dlist;
vtp->dlist.delta = delay;
#if CH_CFG_INTERVALS_SIZE > CH_CFG_ST_RESOLUTION
/* The delta could be too large for the physical timer to handle.*/
@ -202,7 +214,7 @@ void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay,
vt_list_compress(vtlp, deltanow);
delta -= deltanow;
}
else if (delta < vtlp->next->delta) {
else if (delta < vtlp->dlist.next->delta) {
sysinterval_t deadline_delta;
/* A small delay that will become the first element in the delta list
@ -224,28 +236,28 @@ void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay,
/* The delta list is scanned in order to find the correct position for
this timer. */
p = vtlp->next;
while (p->delta < delta) {
dlp = vtlp->dlist.next;
while (dlp->delta < delta) {
/* Debug assert if the timer is already in the list.*/
chDbgAssert(p != vtp, "timer already armed");
chDbgAssert(dlp != &vtp->dlist, "timer already armed");
delta -= p->delta;
p = p->next;
delta -= dlp->delta;
dlp = dlp->next;
}
/* The timer is inserted in the delta list.*/
vtp->next = p;
vtp->prev = vtp->next->prev;
vtp->prev->next = vtp;
p->prev = vtp;
vtp->delta = delta;
vtp->dlist.next = dlp;
vtp->dlist.prev = vtp->dlist.next->prev;
vtp->dlist.prev->next = &vtp->dlist;
dlp->prev = &vtp->dlist;
vtp->dlist.delta = delta;
/* Calculate new delta for the following entry.*/
p->delta -= delta;
dlp->delta -= delta;
/* Special case when the timer is in last position in the list, the
value in the header must be restored.*/
vtlp->delta = (sysinterval_t)-1;
vtlp->dlist.delta = (sysinterval_t)-1;
}
/**
@ -281,37 +293,37 @@ 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, vtp)) {
if (!is_first_timer(&vtlp->dlist, &vtp->dlist)) {
/* Removing the element from the delta list.*/
vtp->prev->next = vtp->next;
vtp->next->prev = vtp->prev;
vtp->dlist.prev->next = vtp->dlist.next;
vtp->dlist.next->prev = vtp->dlist.prev;
vtp->func = NULL;
/* Adding delta to the next element, if it is not the last one.*/
if (is_timer(vtlp, vtp->next))
vtp->next->delta += vtp->delta;
if (is_timer(&vtlp->dlist, vtp->dlist.next))
vtp->dlist.next->delta += vtp->dlist.delta;
return;
}
/* Removing the first timer from the list.*/
vtlp->next = vtp->next;
vtlp->next->prev = (virtual_timer_t *)vtlp;
vtlp->dlist.next = vtp->dlist.next;
vtlp->dlist.next->prev = &vtlp->dlist;
vtp->func = NULL;
/* If the list become empty then the alarm timer is stopped and done.*/
if (is_vtlist_empty(vtlp)) {
if (is_vtlist_empty(&vtlp->dlist)) {
port_timer_stop_alarm();
return;
}
/* The delta of the removed timer is added to the new first timer.*/
vtlp->next->delta += vtp->delta;
vtlp->dlist.next->delta += vtp->dlist.delta;
/* If the new first timer has a delta of zero then the alarm is not
modified, the already programmed alarm will serve it.*/
/* if (vtlp->next->delta == 0) {
/* if (vtlp->dlist.next->delta == 0) {
return;
}*/
@ -320,12 +332,12 @@ void chVTDoResetI(virtual_timer_t *vtp) {
/* If the current time surpassed the time of the next element in list
then the event interrupt is already pending, just return.*/
if (nowdelta >= vtlp->next->delta) {
if (nowdelta >= vtlp->dlist.next->delta) {
return;
}
/* Distance from the next scheduled event and now.*/
delta = vtlp->next->delta - nowdelta;
delta = vtlp->dlist.next->delta - nowdelta;
/* Making sure to not schedule an event closer than CH_CFG_ST_TIMEDELTA
ticks from now.*/
@ -379,12 +391,12 @@ void chVTDoTickI(void) {
}
}
#else /* CH_CFG_ST_TIMEDELTA > 0 */
virtual_timer_t *vtp;
delta_list_t *dlp;
systime_t now;
sysinterval_t delta, nowdelta;
/* Looping through timers.*/
vtp = vtlp->next;
dlp = vtlp->dlist.next;
while (true) {
/* Getting the system time as reference.*/
@ -392,29 +404,32 @@ void chVTDoTickI(void) {
nowdelta = chTimeDiffX(vtlp->lasttime, now);
/* The list scan is limited by the timers header having
"vtlp->vt_delta == (sysinterval_t)-1" which is
"vtlp->dlist.delta == (sysinterval_t)-1" which is
greater than all deltas.*/
if (nowdelta < vtp->delta) {
if (nowdelta < dlp->delta) {
break;
}
/* Consuming all timers between "vtp->lasttime" and now.*/
do {
vtfunc_t fn;
virtual_timer_t *vtp = (virtual_timer_t *)dlp;
/* The "last time" becomes this timer's expiration time.*/
vtlp->lasttime += vtp->delta;
nowdelta -= vtp->delta;
vtlp->lasttime += dlp->delta;
nowdelta -= dlp->delta;
vtp->next->prev = (virtual_timer_t *)vtlp;
vtlp->next = vtp->next;
/* Removing the timer from the list.*/
dlp->next->prev = &vtlp->dlist;
vtlp->dlist.next = dlp->next;
/* Calling the associated function and then marking the timer as
non active.*/
fn = vtp->func;
/* Marking the timer as non active.*/
vtp->func = NULL;
/* If the list becomes empty then the timer is stopped.*/
if (is_vtlist_empty(vtlp)) {
if (is_vtlist_empty(&vtlp->dlist)) {
port_timer_stop_alarm();
}
@ -424,23 +439,23 @@ void chVTDoTickI(void) {
chSysLockFromISR();
/* Next element in the list.*/
vtp = vtlp->next;
dlp = vtlp->dlist.next;
}
while (vtp->delta <= nowdelta);
while (dlp->delta <= nowdelta);
}
/* If the list is empty, nothing else to do.*/
if (is_vtlist_empty(vtlp)) {
if (is_vtlist_empty(&vtlp->dlist)) {
return;
}
/* The "unprocessed nowdelta" time slice is added to "last time"
and subtracted to next timer's delta.*/
vtlp->lasttime += nowdelta;
vtlp->next->delta -= nowdelta;
vtlp->dlist.next->delta -= nowdelta;
/* Recalculating the next alarm time.*/
delta = vtp->delta - chTimeDiffX(vtlp->lasttime, now);
delta = dlp->delta - chTimeDiffX(vtlp->lasttime, now);
if (delta < (sysinterval_t)CH_CFG_ST_TIMEDELTA) {
delta = (sysinterval_t)CH_CFG_ST_TIMEDELTA;
}

View File

@ -246,7 +246,7 @@ static void rt_test_007_003_execute(void) {
{
msg = chSemWaitTimeout(&sem1, TIME_IMMEDIATE);
test_assert(msg == MSG_TIMEOUT, "wrong wake-up message");
test_assert(queue_isempty(&sem1.queue), "queue not empty");
test_assert(ch_queue_isempty(&sem1.queue), "queue not empty");
test_assert(sem1.cnt == 0, "counter not zero");
}
test_end_step(1);
@ -259,7 +259,7 @@ static void rt_test_007_003_execute(void) {
msg = chSemWaitTimeout(&sem1, TIME_MS2I(500));
test_wait_threads();
test_assert(msg == MSG_OK, "wrong wake-up message");
test_assert(queue_isempty(&sem1.queue), "queue not empty");
test_assert(ch_queue_isempty(&sem1.queue), "queue not empty");
test_assert(sem1.cnt == 0, "counter not zero");
}
test_end_step(2);
@ -272,7 +272,7 @@ static void rt_test_007_003_execute(void) {
test_emit_token('A' + i);
msg = chSemWaitTimeout(&sem1, TIME_MS2I(50));
test_assert(msg == MSG_TIMEOUT, "wrong wake-up message");
test_assert(queue_isempty(&sem1.queue), "queue not empty");
test_assert(ch_queue_isempty(&sem1.queue), "queue not empty");
test_assert(sem1.cnt == 0, "counter not zero");
}
test_assert_sequence("ABCDE", "invalid sequence");
@ -386,7 +386,7 @@ static void rt_test_007_005_execute(void) {
test_set_step(2);
{
chSemSignalWait(&sem1, &sem1);
test_assert(queue_isempty(&sem1.queue), "queue not empty");
test_assert(ch_queue_isempty(&sem1.queue), "queue not empty");
test_assert(sem1.cnt == 0, "counter not zero");
}
test_end_step(2);
@ -397,7 +397,7 @@ static void rt_test_007_005_execute(void) {
test_set_step(3);
{
chSemSignalWait(&sem1, &sem1);
test_assert(queue_isempty(&sem1.queue), "queue not empty");
test_assert(ch_queue_isempty(&sem1.queue), "queue not empty");
test_assert(sem1.cnt == 0, "counter not zero");
}
test_end_step(3);

View File

@ -648,7 +648,7 @@ static void rt_test_008_005_execute(void) {
{
chMtxUnlock(&m1);
test_assert(m1.owner == NULL, "still owned");
test_assert(queue_isempty(&m1.queue), "queue not empty");
test_assert(ch_queue_isempty(&m1.queue), "queue not empty");
}
test_end_step(4);
@ -669,7 +669,7 @@ static void rt_test_008_005_execute(void) {
chMtxUnlockAll();
test_assert(m1.owner == NULL, "still owned");
test_assert(queue_isempty(&m1.queue), "queue not empty");
test_assert(ch_queue_isempty(&m1.queue), "queue not empty");
}
test_end_step(6);