git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@13979 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2020-12-24 15:01:05 +00:00
parent 7ab26d58b5
commit 73db4eb94a
24 changed files with 941 additions and 737 deletions

View File

@ -104,6 +104,7 @@ extern "C" {
/* Base kernel headers.*/ /* Base kernel headers.*/
#include "chtypes.h" /* CHTODO: Rename and rework.*/ #include "chtypes.h" /* CHTODO: Rename and rework.*/
#include "chsystypes.h" #include "chsystypes.h"
#include "chlists.h"
#include "chdebug.h" #include "chdebug.h"
#include "chtime.h" #include "chtime.h"
#include "chalign.h" #include "chalign.h"

View File

@ -57,7 +57,7 @@
* @brief condition_variable_t structure. * @brief condition_variable_t structure.
*/ */
typedef struct condition_variable { typedef struct condition_variable {
threads_queue_t queue; /**< @brief Condition variable ch_queue_t queue; /**< @brief Condition variable
threads queue. */ threads queue. */
} condition_variable_t; } condition_variable_t;
@ -72,7 +72,7 @@ typedef struct condition_variable {
* *
* @param[in] name the name of the 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. * @brief Static condition variable initializer.

406
os/rt/include/chlists.h Normal file
View File

@ -0,0 +1,406 @@
/*
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio.
This file is part of ChibiOS.
ChibiOS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file chlists.h
* @brief Lists and Queues header.
*
* @addtogroup os_lists
* @{
*/
#ifndef CHLISTS_H
#define CHLISTS_H
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Module pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
/**
* @brief Type of a generic single link list header and element.
*/
typedef struct ch_list ch_list_t;
/**
* @brief Structure representing a generic single link list header
* and element.
*/
struct ch_list {
ch_list_t *next; /**< @brief Next in the list/queue. */
};
/**
* @brief Type of a generic bidirectional linked list header and element.
*/
typedef struct ch_queue ch_queue_t;
/**
* @brief Structure representing a generic bidirectional linked list header
* and element.
*/
struct ch_queue {
ch_queue_t *next; /**< @brief Next in the list/queue. */
ch_queue_t *prev; /**< @brief Previous in the queue. */
};
/**
* @brief Type of a generic priority-ordered bidirectional linked list
* header and element.
*/
typedef struct ch_priority_queue ch_priority_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.
*/
struct ch_priority_queue {
ch_priority_queue_t *next; /**< @brief Next in the list/queue. */
ch_priority_queue_t *prev; /**< @brief Previous in the queue. */
tprio_t prio;
};
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
/**
* @brief Data part of a static queue object initializer.
* @details This macro should be used when statically initializing a
* queue that is part of a bigger structure.
*
* @param[in] name the name of the queue variable
*/
#define _CH_QUEUE_DATA(name) {(ch_queue_t *)&name, (ch_queue_t *)&name}
/**
* @brief Static queue object initializer.
* @details Statically initialized queues require no explicit
* initialization using @p queue_init().
*
* @param[in] name the name of the queue variable
*/
#define CH_QUEUE_DECL(name) \
ch_queue_t name = _CH_QUEUE_DATA(name)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
/* Early function prototypes required by the following headers.*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
/*===========================================================================*/
/* Module inline functions. */
/*===========================================================================*/
/**
* @brief List initialization.
*
* @param[out] lp pointer to the list header
*
* @notapi
*/
static inline void ch_list_init(ch_list_t *lp) {
lp->next = lp;
}
/**
* @brief Evaluates to @p true if the specified list is empty.
*
* @param[in] lp pointer to the list header
* @return The status of the list.
*
* @notapi
*/
static inline bool ch_list_isempty(ch_list_t *lp) {
return (bool)(lp->next == lp);
}
/**
* @brief Evaluates to @p true if the specified list is not empty.
*
* @param[in] lp pointer to the list header
* @return The status of the list.
*
* @notapi
*/
static inline bool ch_list_notempty(ch_list_t *lp) {
return (bool)(lp->next != lp);
}
/**
* @brief Pushes an element on top of a stack list.
*
* @param[in] p the pointer to the element to be inserted in the list
* @param[in] lp the pointer to the list header
*
* @notapi
*/
static inline void ch_list_push(ch_list_t *p, ch_list_t *lp) {
p->next = lp->next;
lp->next = p;
}
/**
* @brief Pops an element from the top of a stack list and returns it.
* @pre The list must be non-empty before calling this function.
*
* @param[in] lp the pointer to the list header
* @return The removed element pointer.
*
* @notapi
*/
static inline ch_list_t *ch_list_pop(ch_list_t *lp) {
ch_list_t *p = lp->next;
lp->next = p->next;
return p;
}
/**
* @brief Queue initialization.
*
* @param[out] qp pointer to the queue header
*
* @notapi
*/
static inline void ch_queue_init(ch_queue_t *qp) {
qp->next = qp;
qp->prev = qp;
}
/**
* @brief Evaluates to @p true if the specified queue is empty.
*
* @param[in] qp pointer to the queue header
* @return The status of the queue.
*
* @notapi
*/
static inline bool ch_queue_isempty(const ch_queue_t *qp) {
return (bool)(qp->next == qp);
}
/**
* @brief Evaluates to @p true if the specified queue is not empty.
*
* @param[in] qp pointer to the queue header
* @return The status of the queue.
*
* @notapi
*/
static inline bool ch_queue_notempty(const ch_queue_t *qp) {
return (bool)(qp->next != qp);
}
/**
* @brief Inserts an element into a queue.
*
* @param[in] p the pointer to the element to be inserted in the queue
* @param[in] qp the pointer to the queue header
*
* @notapi
*/
static inline void ch_queue_insert(ch_queue_t *p, ch_queue_t *qp) {
p->next = qp;
p->prev = qp->prev;
p->prev->next = p;
qp->prev = p;
}
/**
* @brief Removes the first-out element from a queue and returns it.
* @note If the queue is priority ordered then this function returns the
* element with the highest priority.
*
* @param[in] qp the pointer to the queue list header
* @return The removed element pointer.
*
* @notapi
*/
static inline ch_queue_t *ch_queue_fifo_remove(ch_queue_t *qp) {
ch_queue_t *p = qp->next;
qp->next = p->next;
qp->next->prev = qp;
return p;
}
/**
* @brief Removes the last-out element from a queue and returns it.
* @note If the queue is priority ordered then this function returns the
* element with the lowest priority.
*
* @param[in] qp the pointer to the queue list header
* @return The removed element pointer.
*
* @notapi
*/
static inline ch_queue_t *ch_queue_lifo_remove(ch_queue_t *qp) {
ch_queue_t *p = qp->prev;
qp->prev = p->prev;
qp->prev->next = qp;
return p;
}
/**
* @brief Removes an element from a queue and returns it.
* @details The element is removed from the queue regardless of its relative
* position and regardless the used insertion method.
*
* @param[in] p the pointer to the element to be removed from the queue
* @return The removed element pointer.
*
* @notapi
*/
static inline ch_queue_t *ch_queue_dequeue(ch_queue_t *p) {
p->prev->next = p->next;
p->next->prev = p->prev;
return p;
}
/**
* @brief Priority queue initialization.
* @note The queue header priority is initialized to zero, all other
* elements in the queue are assumed to have priority greater
* than zero.
*
* @param[out] pqp pointer to the priority queue header
*
* @notapi
*/
static inline void ch_pqueue_init(ch_priority_queue_t *pqp) {
pqp->next = pqp;
pqp->prev = pqp;
pqp->prio = (tprio_t)0;
}
/**
* @brief Removes the highest priority element from a priority queue and
* returns it.
*
* @param[in] pqp the pointer to the priority queue list header
* @return The removed element pointer.
*
* @notapi
*/
static inline ch_priority_queue_t *ch_pqueue_remove_highest(ch_priority_queue_t *pqp) {
ch_priority_queue_t *p = pqp->next;
pqp->next = p->next;
pqp->next->prev = pqp;
return p;
}
/**
* @brief Inserts an element in the priority queue placing it behind
* its peers.
* @details The element is positioned behind all elements with higher or
* equal priority.
*
* @param[in] pqp the pointer to the priority queue list header
* @param[in] p the pointer to the element to be inserted in the queue
* @return The inserted element pointer.
*
* @notapi
*/
static inline ch_priority_queue_t *ch_pqueue_insert_behind(ch_priority_queue_t *pqp,
ch_priority_queue_t *p) {
/* Scanning priority queue.*/
do {
pqp = pqp->next;
} while (pqp->prio >= p->prio);
/* Insertion on prev.*/
p->next = pqp;
p->prev = pqp->prev;
p->prev->next = p;
pqp->prev = p;
return p;
}
/**
* @brief Inserts an element in the priority queue placing it ahead of
* its peers.
* @details The element is positioned ahead of all elements with higher or
* equal priority.
*
* @param[in] pqp the pointer to the priority queue list header
* @param[in] p the pointer to the element to be inserted in the queue
* @return The inserted element pointer.
*
* @notapi
*/
static inline ch_priority_queue_t *ch_pqueue_insert_ahead(ch_priority_queue_t *pqp,
ch_priority_queue_t *p) {
/* Scanning priority queue.*/
do {
pqp = pqp->next;
} while (pqp->prio > p->prio);
/* Insertion on prev.*/
p->next = pqp;
p->prev = pqp->prev;
p->prev->next = p;
pqp->prev = p;
return p;
}
#endif /* CHLISTS_H */
/** @} */

View File

@ -168,7 +168,7 @@ static inline bool chMsgIsPendingI(thread_t *tp) {
chDbgCheckClassI(); 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. * @brief Mutex structure.
*/ */
struct ch_mutex { 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. */ on this mutex. */
thread_t *owner; /**< @brief Owner @p thread_t pointer or thread_t *owner; /**< @brief Owner @p thread_t pointer or
@p NULL. */ @p NULL. */
@ -78,9 +78,9 @@ struct ch_mutex {
* @param[in] name the name of the mutex variable * @param[in] name the name of the mutex variable
*/ */
#if (CH_CFG_USE_MUTEXES_RECURSIVE == TRUE) || defined(__DOXYGEN__) #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 #else
#define _MUTEX_DATA(name) {_THREADS_QUEUE_DATA(name.queue), NULL, NULL} #define _MUTEX_DATA(name) {_CH_QUEUE_DATA(name.queue), NULL, NULL}
#endif #endif
/** /**
@ -129,7 +129,7 @@ static inline bool chMtxQueueNotEmptyS(mutex_t *mp) {
chDbgCheckClassS(); chDbgCheckClassS();
return queue_notempty(&mp->queue); return ch_queue_notempty(&mp->queue);
} }
/** /**

View File

@ -119,19 +119,11 @@
/*===========================================================================*/ /*===========================================================================*/
/** /**
* @brief Generic threads single link list, it works like a stack. * @brief Type of a threads queue.
*/ */
struct ch_threads_list { typedef struct ch_threads_queue {
thread_t *next; /**< @brief Next in the list/queue. */ ch_queue_t queue; /**< @brief Threads queue header. */
}; } threads_queue_t;
/**
* @brief Generic threads bidirectional linked list header and element.
*/
struct ch_threads_queue {
thread_t *next; /**< @brief Next in the list/queue. */
thread_t *prev; /**< @brief Previous in the queue. */
};
/** /**
* @brief Structure representing a thread. * @brief Structure representing a thread.
@ -140,8 +132,12 @@ struct ch_threads_queue {
* by shrinking this structure. * by shrinking this structure.
*/ */
struct ch_thread { struct ch_thread {
threads_queue_t queue; /**< @brief Threads queue header. */ union {
tprio_t prio; /**< @brief Thread priority. */ ch_list_t list; /**< @brief Threads lists element. */
ch_queue_t queue; /**< @brief Threads queues element. */
ch_priority_queue_t pqueue; /**< @brief Threads ordered queues
element. */
} hdr;
struct port_context ctx; /**< @brief Processor context. */ struct port_context ctx; /**< @brief Processor context. */
#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__) #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
thread_t *newer; /**< @brief Newer registry element. */ thread_t *newer; /**< @brief Newer registry element. */
@ -261,13 +257,13 @@ struct ch_thread {
/** /**
* @brief Termination waiting list. * @brief Termination waiting list.
*/ */
threads_list_t waiting; ch_list_t waiting;
#endif #endif
#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__) #if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
/** /**
* @brief Messages queue. * @brief Messages queue.
*/ */
threads_queue_t msgqueue; ch_queue_t msgqueue;
#endif #endif
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__) #if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
/** /**
@ -306,32 +302,43 @@ struct ch_thread {
}; };
/** /**
* @extends virtual_timers_list_t * @brief Type of a Virtual Timer callback function.
*
* @brief Virtual Timer descriptor structure.
*/ */
struct ch_virtual_timer { typedef void (*vtfunc_t)(void *p);
virtual_timer_t *next; /**< @brief Next timer in the list. */
virtual_timer_t *prev; /**< @brief Previous timer in the list. */ /**
* @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 {
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. */ 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 vtfunc_t func; /**< @brief Timer callback function
pointer. */ pointer. */
void *par; /**< @brief Timer callback function void *par; /**< @brief Timer callback function
parameter. */ parameter. */
}; } virtual_timer_t;
/** /**
* @brief Virtual timers list header. * @brief Type of virtual timers list header.
* @note The timers list is implemented as a double link bidirectional list * @note The timers list is implemented as a double link bidirectional list
* in order to make the unlink time constant, the reset of a virtual * in order to make the unlink time constant, the reset of a virtual
* timer is often used in the code. * timer is often used in the code.
*/ */
struct ch_virtual_timers_list { typedef struct ch_virtual_timers_list {
virtual_timer_t *next; /**< @brief Next timer in the delta delta_list_t dlist; /**< @brief Delta list header. */
list. */
virtual_timer_t *prev; /**< @brief Last timer in the delta
list. */
sysinterval_t delta; /**< @brief Must be initialized to -1. */
#if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__) #if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__)
volatile systime_t systime; /**< @brief System Time counter. */ volatile systime_t systime; /**< @brief System Time counter. */
#endif #endif
@ -342,24 +349,36 @@ struct ch_virtual_timers_list {
systime_t lasttime; /**< @brief System time of the last systime_t lasttime; /**< @brief System time of the last
tick event. */ tick event. */
#endif #endif
}; } virtual_timers_list_t;
/** /**
* @extends threads_queue_t * @extends threads_queue_t
*/ */
struct ch_ready_list { struct ch_ready_list {
threads_queue_t queue; /**< @brief Threads queue. */ /**
tprio_t prio; /**< @brief This field must be * @brief Threads ordered queues header.
initialized to zero. */ * @note The priority field must be initialized to zero.
struct port_context ctx; /**< @brief Not used, present because */
offsets. */ ch_priority_queue_t pqueue;
/**
* @brief Not used, present because offsets.
*/
struct port_context ctx;
#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__) #if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
thread_t *newer; /**< @brief Newer registry element. */ /**
thread_t *older; /**< @brief Older registry element. */ * @brief Newer registry element.
*/
thread_t *newer;
/**
* @brief Older registry element.
*/
thread_t *older;
#endif #endif
/* End of the fields shared with the thread_t structure.*/ /* End of the fields shared with the thread_t structure.*/
thread_t *current; /**< @brief The currently running /**
thread. */ * @brief The currently running thread.
*/
thread_t *current;
}; };
/** /**
@ -473,13 +492,7 @@ extern "C" {
void chSchDoRescheduleAhead(void); void chSchDoRescheduleAhead(void);
void chSchDoReschedule(void); void chSchDoReschedule(void);
#if CH_CFG_OPTIMIZE_SPEED == FALSE #if CH_CFG_OPTIMIZE_SPEED == FALSE
void queue_prio_insert(thread_t *tp, threads_queue_t *tqp); void ch_sch_prio_insert(ch_queue_t *tp, ch_queue_t *qp);
void queue_insert(thread_t *tp, threads_queue_t *tqp);
thread_t *queue_fifo_remove(threads_queue_t *tqp);
thread_t *queue_lifo_remove(threads_queue_t *tqp);
thread_t *queue_dequeue(thread_t *tp);
void list_insert(thread_t *tp, threads_list_t *tlp);
thread_t *list_remove(threads_list_t *tlp);
#endif /* CH_CFG_OPTIMIZE_SPEED == FALSE */ #endif /* CH_CFG_OPTIMIZE_SPEED == FALSE */
#ifdef __cplusplus #ifdef __cplusplus
} }
@ -489,144 +502,20 @@ extern "C" {
/* Module inline functions. */ /* 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 /* If the performance code path has been chosen then all the following
functions are inlined into the various kernel modules.*/ functions are inlined into the various kernel modules.*/
#if CH_CFG_OPTIMIZE_SPEED == TRUE #if CH_CFG_OPTIMIZE_SPEED == TRUE
static inline void list_insert(thread_t *tp, threads_list_t *tlp) { static inline void ch_sch_prio_insert(ch_queue_t *tp, ch_queue_t *qp) {
tp->queue.next = tlp->next; ch_queue_t *cp = qp;
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) {
thread_t *cp = (thread_t *)tqp;
do { do {
cp = cp->queue.next; cp = cp->next;
} while ((cp != (thread_t *)tqp) && (cp->prio >= tp->prio)); } while ((cp != qp) &&
tp->queue.next = cp; (((thread_t *)cp)->hdr.pqueue.prio >= ((thread_t *)tp)->hdr.pqueue.prio));
tp->queue.prev = cp->queue.prev; tp->next = cp;
tp->queue.prev->queue.next = tp; tp->prev = cp->prev;
cp->queue.prev = tp; tp->prev->next = tp;
} cp->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;
} }
#endif /* CH_CFG_OPTIMIZE_SPEED == TRUE */ #endif /* CH_CFG_OPTIMIZE_SPEED == TRUE */
@ -645,7 +534,7 @@ static inline bool chSchIsRescRequiredI(void) {
chDbgCheckClassI(); chDbgCheckClassI();
return firstprio(&ch.rlist.queue) > currp->prio; return firstprio(&ch.rlist.pqueue) > currp->hdr.pqueue.prio;
} }
/** /**
@ -663,7 +552,7 @@ static inline bool chSchCanYieldS(void) {
chDbgCheckClassS(); chDbgCheckClassS();
return firstprio(&ch.rlist.queue) >= currp->prio; return firstprio(&ch.rlist.pqueue) >= currp->hdr.pqueue.prio;
} }
/** /**
@ -690,8 +579,8 @@ static inline void chSchDoYieldS(void) {
* @special * @special
*/ */
static inline void chSchPreemption(void) { static inline void chSchPreemption(void) {
tprio_t p1 = firstprio(&ch.rlist.queue); tprio_t p1 = firstprio(&ch.rlist.pqueue);
tprio_t p2 = currp->prio; tprio_t p2 = currp->hdr.pqueue.prio;
#if CH_CFG_TIME_QUANTUM > 0 #if CH_CFG_TIME_QUANTUM > 0
if (currp->ticks > (tslices_t)0) { if (currp->ticks > (tslices_t)0) {

View File

@ -50,7 +50,7 @@
* @brief Semaphore structure. * @brief Semaphore structure.
*/ */
typedef struct ch_semaphore { 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. */ on this semaphore. */
cnt_t cnt; /**< @brief The semaphore counter. */ cnt_t cnt; /**< @brief The semaphore counter. */
} semaphore_t; } semaphore_t;
@ -68,7 +68,7 @@ typedef struct ch_semaphore {
* @param[in] n the counter initial value, this value must be * @param[in] n the counter initial value, this value must be
* non-negative * 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. * @brief Static semaphore initializer.

View File

@ -371,8 +371,8 @@ static inline void chSysUnlock(void) {
in a critical section not followed by a chSchRescheduleS(), this means in a critical section not followed by a chSchRescheduleS(), this means
that the current thread has a lower priority than the next thread in that the current thread has a lower priority than the next thread in
the ready list.*/ the ready list.*/
chDbgAssert((ch.rlist.queue.next == (thread_t *)&ch.rlist.queue) || chDbgAssert((ch.rlist.pqueue.next == &ch.rlist.pqueue) ||
(ch.rlist.current->prio >= ch.rlist.queue.next->prio), (ch.rlist.current->hdr.pqueue.prio >= ch.rlist.pqueue.next->prio),
"priority order violation"); "priority order violation");
port_unlock(); port_unlock();
@ -460,7 +460,7 @@ static inline void chSysUnconditionalUnlock(void) {
*/ */
static inline thread_t *chSysGetIdleThreadX(void) { static inline thread_t *chSysGetIdleThreadX(void) {
return ch.rlist.queue.prev; return (thread_t *)ch.rlist.pqueue.prev;
} }
#endif /* CH_CFG_NO_IDLE_THREAD == FALSE */ #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 * @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. * @brief Static threads queue object initializer.
@ -104,7 +104,7 @@ typedef struct {
* *
* @param[in] name the name of the threads queue variable * @param[in] name the name of the threads queue variable
*/ */
#define _THREADS_QUEUE_DECL(name) \ #define THREADS_QUEUE_DECL(name) \
threads_queue_t name = _THREADS_QUEUE_DATA(name) threads_queue_t name = _THREADS_QUEUE_DATA(name)
/** @} */ /** @} */
@ -284,7 +284,7 @@ static inline thread_t *chThdGetSelfX(void) {
*/ */
static inline tprio_t chThdGetPriorityX(void) { static inline tprio_t chThdGetPriorityX(void) {
return chThdGetSelfX()->prio; return chThdGetSelfX()->hdr.pqueue.prio;
} }
/** /**
@ -391,7 +391,7 @@ static inline void chThdSleepS(sysinterval_t ticks) {
*/ */
static inline void chThdQueueObjectInit(threads_queue_t *tqp) { static inline void chThdQueueObjectInit(threads_queue_t *tqp) {
queue_init(tqp); ch_queue_init(&tqp->queue);
} }
/** /**
@ -408,7 +408,7 @@ static inline bool chThdQueueIsEmptyI(threads_queue_t *tqp) {
chDbgCheckClassI(); chDbgCheckClassI();
return queue_isempty(tqp); return ch_queue_isempty(&tqp->queue);
} }
/** /**
@ -425,9 +425,9 @@ static inline bool chThdQueueIsEmptyI(threads_queue_t *tqp) {
static inline void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg) { static inline void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg) {
thread_t *tp; 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"); chDbgAssert(tp->state == CH_STATE_QUEUED, "invalid state");

View File

@ -208,19 +208,21 @@ static inline bool chVTIsSystemTimeWithin(systime_t start, systime_t end) {
* @iclass * @iclass
*/ */
static inline bool chVTGetTimersStateI(sysinterval_t *timep) { static inline bool chVTGetTimersStateI(sysinterval_t *timep) {
virtual_timers_list_t *vtlp = &ch.vtlist;
delta_list_t *dlp = &vtlp->dlist;
chDbgCheckClassI(); chDbgCheckClassI();
if (&ch.vtlist == (virtual_timers_list_t *)ch.vtlist.next) { if (dlp == dlp->next) {
return false; return false;
} }
if (timep != NULL) { if (timep != NULL) {
#if CH_CFG_ST_TIMEDELTA == 0 #if CH_CFG_ST_TIMEDELTA == 0
*timep = ch.vtlist.next->delta; *timep = dlp->next->delta;
#else #else
*timep = (ch.vtlist.next->delta + (sysinterval_t)CH_CFG_ST_TIMEDELTA) - *timep = (dlp->next->delta + (sysinterval_t)CH_CFG_ST_TIMEDELTA) -
chTimeDiffX(ch.vtlist.lasttime, chVTGetSystemTimeX()); chTimeDiffX(vtlp->lasttime, chVTGetSystemTimeX());
#endif #endif
} }

View File

@ -76,7 +76,7 @@ void chCondObjectInit(condition_variable_t *cp) {
chDbgCheck(cp != NULL); 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); chDbgCheck(cp != NULL);
chSysLock(); chSysLock();
if (queue_notempty(&cp->queue)) { if (ch_queue_notempty(&cp->queue)) {
chSchWakeupS(queue_fifo_remove(&cp->queue), MSG_OK); chSchWakeupS((thread_t *)ch_queue_fifo_remove(&cp->queue), MSG_OK);
} }
chSysUnlock(); chSysUnlock();
} }
@ -113,8 +113,8 @@ void chCondSignalI(condition_variable_t *cp) {
chDbgCheckClassI(); chDbgCheckClassI();
chDbgCheck(cp != NULL); chDbgCheck(cp != NULL);
if (queue_notempty(&cp->queue)) { if (ch_queue_notempty(&cp->queue)) {
thread_t *tp = queue_fifo_remove(&cp->queue); thread_t *tp = (thread_t *)ch_queue_fifo_remove(&cp->queue);
tp->u.rdymsg = MSG_OK; tp->u.rdymsg = MSG_OK;
(void) chSchReadyI(tp); (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 /* 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 ready list in FIFO order. The wakeup message is set to @p MSG_RESET in
order to make a chCondBroadcast() detectable from a chCondSignal().*/ order to make a chCondBroadcast() detectable from a chCondSignal().*/
while (queue_notempty(&cp->queue)) { while (ch_queue_notempty(&cp->queue)) {
chSchReadyI(queue_fifo_remove(&cp->queue))->u.rdymsg = MSG_RESET; chSchReadyI((thread_t *)ch_queue_fifo_remove(&cp->queue))->u.rdymsg = MSG_RESET;
} }
} }
@ -217,7 +217,7 @@ msg_t chCondWaitS(condition_variable_t *cp) {
/* Start waiting on the condition variable, on exit the mutex is taken /* Start waiting on the condition variable, on exit the mutex is taken
again.*/ again.*/
ctp->u.wtobjp = cp; ctp->u.wtobjp = cp;
queue_prio_insert(ctp, &cp->queue); ch_sch_prio_insert(&ctp->hdr.queue, &cp->queue);
chSchGoSleepS(CH_STATE_WTCOND); chSchGoSleepS(CH_STATE_WTCOND);
msg = ctp->u.rdymsg; msg = ctp->u.rdymsg;
chMtxLockS(mp); chMtxLockS(mp);
@ -306,7 +306,7 @@ msg_t chCondWaitTimeoutS(condition_variable_t *cp, sysinterval_t timeout) {
/* Start waiting on the condition variable, on exit the mutex is taken /* Start waiting on the condition variable, on exit the mutex is taken
again.*/ again.*/
currp->u.wtobjp = cp; currp->u.wtobjp = cp;
queue_prio_insert(currp, &cp->queue); ch_sch_prio_insert(&currp->hdr.queue, &cp->queue);
msg = chSchGoSleepTimeoutS(CH_STATE_WTCOND, timeout); msg = chSchGoSleepTimeoutS(CH_STATE_WTCOND, timeout);
if (msg != MSG_TIMEOUT) { if (msg != MSG_TIMEOUT) {
chMtxLockS(mp); chMtxLockS(mp);

View File

@ -64,9 +64,9 @@
/*===========================================================================*/ /*===========================================================================*/
#if CH_CFG_USE_MESSAGES_PRIORITY == TRUE #if CH_CFG_USE_MESSAGES_PRIORITY == TRUE
#define msg_insert(tp, qp) queue_prio_insert(tp, qp) #define msg_insert(tp, qp) ch_sch_prio_insert(&tp->hdr.queue, qp)
#else #else
#define msg_insert(tp, qp) queue_insert(tp, qp) #define msg_insert(tp, qp) ch_queue_insert(&tp->hdr.queue, qp)
#endif #endif
/*===========================================================================*/ /*===========================================================================*/
@ -126,7 +126,7 @@ thread_t *chMsgWaitS(void) {
if (!chMsgIsPendingI(currp)) { if (!chMsgIsPendingI(currp)) {
chSchGoSleepS(CH_STATE_WTMSG); chSchGoSleepS(CH_STATE_WTMSG);
} }
tp = queue_fifo_remove(&currp->msgqueue); tp = (thread_t *)ch_queue_fifo_remove(&currp->msgqueue);
tp->state = CH_STATE_SNDMSG; tp->state = CH_STATE_SNDMSG;
return tp; return tp;
@ -164,7 +164,7 @@ thread_t *chMsgWaitTimeoutS(sysinterval_t timeout) {
return NULL; return NULL;
} }
} }
tp = queue_fifo_remove(&currp->msgqueue); tp = (thread_t *)ch_queue_fifo_remove(&currp->msgqueue);
tp->state = CH_STATE_SNDMSG; tp->state = CH_STATE_SNDMSG;
return tp; return tp;
@ -191,7 +191,7 @@ thread_t *chMsgPollS(void) {
thread_t *tp = NULL; thread_t *tp = NULL;
if (chMsgIsPendingI(currp)) { if (chMsgIsPendingI(currp)) {
tp = queue_fifo_remove(&currp->msgqueue); tp = (thread_t *)ch_queue_fifo_remove(&currp->msgqueue);
tp->state = CH_STATE_SNDMSG; tp->state = CH_STATE_SNDMSG;
} }

View File

@ -104,7 +104,7 @@ void chMtxObjectInit(mutex_t *mp) {
chDbgCheck(mp != NULL); chDbgCheck(mp != NULL);
queue_init(&mp->queue); ch_queue_init(&mp->queue);
mp->owner = NULL; mp->owner = NULL;
#if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE #if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE
mp->cnt = (cnt_t)0; mp->cnt = (cnt_t)0;
@ -137,7 +137,7 @@ void chMtxLock(mutex_t *mp) {
* @sclass * @sclass
*/ */
void chMtxLockS(mutex_t *mp) { void chMtxLockS(mutex_t *mp) {
thread_t *ctp = currp; thread_t *currtp = chThdGetSelfX();
chDbgCheckClassS(); chDbgCheckClassS();
chDbgCheck(mp != NULL); chDbgCheck(mp != NULL);
@ -150,7 +150,7 @@ void chMtxLockS(mutex_t *mp) {
/* If the mutex is already owned by this thread, the counter is increased /* If the mutex is already owned by this thread, the counter is increased
and there is no need of more actions.*/ and there is no need of more actions.*/
if (mp->owner == ctp) { if (mp->owner == currtp) {
mp->cnt++; mp->cnt++;
} }
else { else {
@ -162,15 +162,16 @@ void chMtxLockS(mutex_t *mp) {
/* Does the running thread have higher priority than the mutex /* Does the running thread have higher priority than the mutex
owning thread? */ owning thread? */
while (tp->prio < ctp->prio) { while (tp->hdr.pqueue.prio < currtp->hdr.pqueue.prio) {
/* Make priority of thread tp match the running thread's priority.*/ /* Make priority of thread tp match the running thread's priority.*/
tp->prio = ctp->prio; tp->hdr.pqueue.prio = currtp->hdr.pqueue.prio;
/* The following states need priority queues reordering.*/ /* The following states need priority queues reordering.*/
switch (tp->state) { switch (tp->state) {
case CH_STATE_WTMTX: case CH_STATE_WTMTX:
/* Re-enqueues the mutex owner with its new priority.*/ /* Re-enqueues the mutex owner with its new priority.*/
queue_prio_insert(queue_dequeue(tp), &tp->u.wtmtxp->queue); ch_sch_prio_insert(ch_queue_dequeue(&tp->hdr.queue),
&tp->u.wtmtxp->queue);
tp = tp->u.wtmtxp->owner; tp = tp->u.wtmtxp->owner;
/*lint -e{9042} [16.1] Continues the while.*/ /*lint -e{9042} [16.1] Continues the while.*/
continue; continue;
@ -190,7 +191,8 @@ void chMtxLockS(mutex_t *mp) {
case CH_STATE_SNDMSGQ: case CH_STATE_SNDMSGQ:
#endif #endif
/* Re-enqueues tp with its new priority on the queue.*/ /* Re-enqueues tp with its new priority on the queue.*/
queue_prio_insert(queue_dequeue(tp), &tp->u.wtmtxp->queue); ch_sch_prio_insert(ch_queue_dequeue(&tp->hdr.queue),
&tp->u.wtmtxp->queue);
break; break;
#endif #endif
case CH_STATE_READY: case CH_STATE_READY:
@ -199,7 +201,7 @@ void chMtxLockS(mutex_t *mp) {
tp->state = CH_STATE_CURRENT; tp->state = CH_STATE_CURRENT;
#endif #endif
/* Re-enqueues tp with its new priority on the ready list.*/ /* 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; break;
default: default:
/* Nothing to do for other states.*/ /* Nothing to do for other states.*/
@ -209,14 +211,14 @@ void chMtxLockS(mutex_t *mp) {
} }
/* Sleep on the mutex.*/ /* Sleep on the mutex.*/
queue_prio_insert(ctp, &mp->queue); ch_sch_prio_insert(&currtp->hdr.queue, &mp->queue);
ctp->u.wtmtxp = mp; currtp->u.wtmtxp = mp;
chSchGoSleepS(CH_STATE_WTMTX); chSchGoSleepS(CH_STATE_WTMTX);
/* It is assumed that the thread performing the unlock operation assigns /* It is assumed that the thread performing the unlock operation assigns
the mutex to this thread.*/ the mutex to this thread.*/
chDbgAssert(mp->owner == ctp, "not owner"); chDbgAssert(mp->owner == currtp, "not owner");
chDbgAssert(ctp->mtxlist == mp, "not owned"); chDbgAssert(currtp->mtxlist == mp, "not owned");
#if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE #if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE
chDbgAssert(mp->cnt == (cnt_t)1, "counter is not one"); chDbgAssert(mp->cnt == (cnt_t)1, "counter is not one");
} }
@ -229,9 +231,9 @@ void chMtxLockS(mutex_t *mp) {
mp->cnt++; mp->cnt++;
#endif #endif
/* It was not owned, inserted in the owned mutexes list.*/ /* It was not owned, inserted in the owned mutexes list.*/
mp->owner = ctp; mp->owner = currtp;
mp->next = ctp->mtxlist; mp->next = currtp->mtxlist;
ctp->mtxlist = mp; currtp->mtxlist = mp;
} }
} }
@ -280,6 +282,7 @@ bool chMtxTryLock(mutex_t *mp) {
* @sclass * @sclass
*/ */
bool chMtxTryLockS(mutex_t *mp) { bool chMtxTryLockS(mutex_t *mp) {
thread_t *currtp = chThdGetSelfX();
chDbgCheckClassS(); chDbgCheckClassS();
chDbgCheck(mp != NULL); chDbgCheck(mp != NULL);
@ -289,7 +292,7 @@ bool chMtxTryLockS(mutex_t *mp) {
chDbgAssert(mp->cnt >= (cnt_t)1, "counter is not positive"); chDbgAssert(mp->cnt >= (cnt_t)1, "counter is not positive");
if (mp->owner == currp) { if (mp->owner == currtp) {
mp->cnt++; mp->cnt++;
return true; return true;
} }
@ -302,9 +305,9 @@ bool chMtxTryLockS(mutex_t *mp) {
mp->cnt++; mp->cnt++;
#endif #endif
mp->owner = currp; mp->owner = currtp;
mp->next = currp->mtxlist; mp->next = currtp->mtxlist;
currp->mtxlist = mp; currtp->mtxlist = mp;
return true; return true;
} }
@ -321,27 +324,27 @@ bool chMtxTryLockS(mutex_t *mp) {
* @api * @api
*/ */
void chMtxUnlock(mutex_t *mp) { void chMtxUnlock(mutex_t *mp) {
thread_t *ctp = currp; thread_t *currtp = chThdGetSelfX();
mutex_t *lmp; mutex_t *lmp;
chDbgCheck(mp != NULL); chDbgCheck(mp != NULL);
chSysLock(); chSysLock();
chDbgAssert(ctp->mtxlist != NULL, "owned mutexes list empty"); chDbgAssert(currtp->mtxlist != NULL, "owned mutexes list empty");
chDbgAssert(ctp->mtxlist->owner == ctp, "ownership failure"); chDbgAssert(currtp->mtxlist->owner == currtp, "ownership failure");
#if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE #if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE
chDbgAssert(mp->cnt >= (cnt_t)1, "counter is not positive"); chDbgAssert(mp->cnt >= (cnt_t)1, "counter is not positive");
if (--mp->cnt == (cnt_t)0) { if (--mp->cnt == (cnt_t)0) {
#endif #endif
chDbgAssert(ctp->mtxlist == mp, "not next in list"); chDbgAssert(currtp->mtxlist == mp, "not next in list");
/* Removes the top mutex from the thread's owned mutexes list and marks /* Removes the top mutex from the thread's owned mutexes list and marks
it as not owned. Note, it is assumed to be the same mutex passed as it as not owned. Note, it is assumed to be the same mutex passed as
parameter of this function.*/ parameter of this function.*/
ctp->mtxlist = mp->next; currtp->mtxlist = mp->next;
/* If a thread is waiting on the mutex then the fun part begins.*/ /* If a thread is waiting on the mutex then the fun part begins.*/
if (chMtxQueueNotEmptyS(mp)) { if (chMtxQueueNotEmptyS(mp)) {
@ -349,29 +352,29 @@ void chMtxUnlock(mutex_t *mp) {
/* Recalculates the optimal thread priority by scanning the owned /* Recalculates the optimal thread priority by scanning the owned
mutexes list.*/ mutexes list.*/
tprio_t newprio = ctp->realprio; tprio_t newprio = currtp->realprio;
lmp = ctp->mtxlist; lmp = currtp->mtxlist;
while (lmp != NULL) { while (lmp != NULL) {
/* If the highest priority thread waiting in the mutexes list has a /* If the highest priority thread waiting in the mutexes list has a
greater priority than the current thread base priority then the greater priority than the current thread base priority then the
final priority will have at least that priority.*/ final priority will have at least that priority.*/
if (chMtxQueueNotEmptyS(lmp) && if (chMtxQueueNotEmptyS(lmp) &&
(lmp->queue.next->prio > newprio)) { (((thread_t *)lmp->queue.next)->hdr.pqueue.prio > newprio)) {
newprio = lmp->queue.next->prio; newprio = ((thread_t *)lmp->queue.next)->hdr.pqueue.prio;
} }
lmp = lmp->next; lmp = lmp->next;
} }
/* Assigns to the current thread the highest priority among all the /* Assigns to the current thread the highest priority among all the
waiting threads.*/ waiting threads.*/
ctp->prio = newprio; currtp->hdr.pqueue.prio = newprio;
/* Awakens the highest priority thread waiting for the unlocked mutex and /* Awakens the highest priority thread waiting for the unlocked mutex and
assigns the mutex to it.*/ assigns the mutex to it.*/
#if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE #if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE
mp->cnt = (cnt_t)1; mp->cnt = (cnt_t)1;
#endif #endif
tp = queue_fifo_remove(&mp->queue); tp = (thread_t *)ch_queue_fifo_remove(&mp->queue);
mp->owner = tp; mp->owner = tp;
mp->next = tp->mtxlist; mp->next = tp->mtxlist;
tp->mtxlist = mp; tp->mtxlist = mp;
@ -408,26 +411,26 @@ void chMtxUnlock(mutex_t *mp) {
* @sclass * @sclass
*/ */
void chMtxUnlockS(mutex_t *mp) { void chMtxUnlockS(mutex_t *mp) {
thread_t *ctp = currp; thread_t *currtp = chThdGetSelfX();
mutex_t *lmp; mutex_t *lmp;
chDbgCheckClassS(); chDbgCheckClassS();
chDbgCheck(mp != NULL); chDbgCheck(mp != NULL);
chDbgAssert(ctp->mtxlist != NULL, "owned mutexes list empty"); chDbgAssert(currtp->mtxlist != NULL, "owned mutexes list empty");
chDbgAssert(ctp->mtxlist->owner == ctp, "ownership failure"); chDbgAssert(currtp->mtxlist->owner == currtp, "ownership failure");
#if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE #if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE
chDbgAssert(mp->cnt >= (cnt_t)1, "counter is not positive"); chDbgAssert(mp->cnt >= (cnt_t)1, "counter is not positive");
if (--mp->cnt == (cnt_t)0) { if (--mp->cnt == (cnt_t)0) {
#endif #endif
chDbgAssert(ctp->mtxlist == mp, "not next in list"); chDbgAssert(currtp->mtxlist == mp, "not next in list");
/* Removes the top mutex from the thread's owned mutexes list and marks /* Removes the top mutex from the thread's owned mutexes list and marks
it as not owned. Note, it is assumed to be the same mutex passed as it as not owned. Note, it is assumed to be the same mutex passed as
parameter of this function.*/ parameter of this function.*/
ctp->mtxlist = mp->next; currtp->mtxlist = mp->next;
/* If a thread is waiting on the mutex then the fun part begins.*/ /* If a thread is waiting on the mutex then the fun part begins.*/
if (chMtxQueueNotEmptyS(mp)) { if (chMtxQueueNotEmptyS(mp)) {
@ -435,29 +438,29 @@ void chMtxUnlockS(mutex_t *mp) {
/* Recalculates the optimal thread priority by scanning the owned /* Recalculates the optimal thread priority by scanning the owned
mutexes list.*/ mutexes list.*/
tprio_t newprio = ctp->realprio; tprio_t newprio = currtp->realprio;
lmp = ctp->mtxlist; lmp = currtp->mtxlist;
while (lmp != NULL) { while (lmp != NULL) {
/* If the highest priority thread waiting in the mutexes list has a /* If the highest priority thread waiting in the mutexes list has a
greater priority than the current thread base priority then the greater priority than the current thread base priority then the
final priority will have at least that priority.*/ final priority will have at least that priority.*/
if (chMtxQueueNotEmptyS(lmp) && if (chMtxQueueNotEmptyS(lmp) &&
(lmp->queue.next->prio > newprio)) { (((thread_t *)lmp->queue.next)->hdr.pqueue.prio > newprio)) {
newprio = lmp->queue.next->prio; newprio = ((thread_t *)lmp->queue.next)->hdr.pqueue.prio;
} }
lmp = lmp->next; lmp = lmp->next;
} }
/* Assigns to the current thread the highest priority among all the /* Assigns to the current thread the highest priority among all the
waiting threads.*/ waiting threads.*/
ctp->prio = newprio; currtp->hdr.pqueue.prio = newprio;
/* Awakens the highest priority thread waiting for the unlocked mutex and /* Awakens the highest priority thread waiting for the unlocked mutex and
assigns the mutex to it.*/ assigns the mutex to it.*/
#if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE #if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE
mp->cnt = (cnt_t)1; mp->cnt = (cnt_t)1;
#endif #endif
tp = queue_fifo_remove(&mp->queue); tp = (thread_t *)ch_queue_fifo_remove(&mp->queue);
mp->owner = tp; mp->owner = tp;
mp->next = tp->mtxlist; mp->next = tp->mtxlist;
tp->mtxlist = mp; tp->mtxlist = mp;
@ -485,18 +488,18 @@ void chMtxUnlockS(mutex_t *mp) {
* @sclass * @sclass
*/ */
void chMtxUnlockAllS(void) { void chMtxUnlockAllS(void) {
thread_t *ctp = currp; thread_t *currtp = chThdGetSelfX();
if (ctp->mtxlist != NULL) { if (currtp->mtxlist != NULL) {
do { do {
mutex_t *mp = ctp->mtxlist; mutex_t *mp = currtp->mtxlist;
ctp->mtxlist = mp->next; currtp->mtxlist = mp->next;
if (chMtxQueueNotEmptyS(mp)) { if (chMtxQueueNotEmptyS(mp)) {
thread_t *tp; thread_t *tp;
#if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE #if CH_CFG_USE_MUTEXES_RECURSIVE == TRUE
mp->cnt = (cnt_t)1; mp->cnt = (cnt_t)1;
#endif #endif
tp = queue_fifo_remove(&mp->queue); tp = (thread_t *)ch_queue_fifo_remove(&mp->queue);
mp->owner = tp; mp->owner = tp;
mp->next = tp->mtxlist; mp->next = tp->mtxlist;
tp->mtxlist = mp; tp->mtxlist = mp;
@ -508,8 +511,8 @@ void chMtxUnlockAllS(void) {
#endif #endif
mp->owner = NULL; mp->owner = NULL;
} }
} while (ctp->mtxlist != NULL); } while (currtp->mtxlist != NULL);
ctp->prio = ctp->realprio; currtp->hdr.pqueue.prio = currtp->realprio;
chSchRescheduleS(); chSchRescheduleS();
} }
} }

View File

@ -90,7 +90,7 @@ ROMCONST chdebug_t ch_debug = {
(uint8_t)sizeof (void *), (uint8_t)sizeof (void *),
(uint8_t)sizeof (systime_t), (uint8_t)sizeof (systime_t),
(uint8_t)sizeof (thread_t), (uint8_t)sizeof (thread_t),
(uint8_t)_offsetof(thread_t, prio), (uint8_t)_offsetof(thread_t, hdr.pqueue.prio),
(uint8_t)_offsetof(thread_t, ctx), (uint8_t)_offsetof(thread_t, ctx),
(uint8_t)_offsetof(thread_t, newer), (uint8_t)_offsetof(thread_t, newer),
(uint8_t)_offsetof(thread_t, older), (uint8_t)_offsetof(thread_t, older),

View File

@ -53,266 +53,6 @@ ch_system_t ch;
/* Module local functions. */ /* Module local functions. */
/*===========================================================================*/ /*===========================================================================*/
/*===========================================================================*/
/* Module exported functions. */
/*===========================================================================*/
/**
* @brief Scheduler initialization.
*
* @notapi
*/
void _scheduler_init(void) {
queue_init(&ch.rlist.queue);
ch.rlist.prio = NOPRIO;
#if CH_CFG_USE_REGISTRY == TRUE
ch.rlist.newer = (thread_t *)&ch.rlist;
ch.rlist.older = (thread_t *)&ch.rlist;
#endif
}
#if (CH_CFG_OPTIMIZE_SPEED == FALSE) || defined(__DOXYGEN__)
/**
* @brief Inserts a thread into a priority ordered queue.
* @note The insertion is done by scanning the list from the highest
* priority toward the lowest.
*
* @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_prio_insert(thread_t *tp, threads_queue_t *tqp) {
thread_t *cp = (thread_t *)tqp;
do {
cp = cp->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;
}
/**
* @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 */
/**
* @brief Inserts a thread in the Ready List placing it behind its peers.
* @details The thread is positioned behind all threads with higher or equal
* priority.
* @pre The thread must not be already inserted in any list through its
* @p next and @p prev or list corruption would occur.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
*
* @param[in] tp the thread to be made ready
* @return The thread pointer.
*
* @iclass
*/
thread_t *chSchReadyI(thread_t *tp) {
thread_t *cp;
chDbgCheckClassI();
chDbgCheck(tp != NULL);
chDbgAssert((tp->state != CH_STATE_READY) &&
(tp->state != CH_STATE_FINAL),
"invalid state");
tp->state = CH_STATE_READY;
cp = (thread_t *)&ch.rlist.queue;
do {
cp = cp->queue.next;
} while (cp->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;
return tp;
}
/**
* @brief Inserts a thread in the Ready List placing it ahead its peers.
* @details The thread is positioned ahead all threads with higher or equal
* priority.
* @pre The thread must not be already inserted in any list through its
* @p next and @p prev or list corruption would occur.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
*
* @param[in] tp the thread to be made ready
* @return The thread pointer.
*
* @iclass
*/
thread_t *chSchReadyAheadI(thread_t *tp) {
thread_t *cp;
chDbgCheckClassI();
chDbgCheck(tp != NULL);
chDbgAssert((tp->state != CH_STATE_READY) &&
(tp->state != CH_STATE_FINAL),
"invalid state");
tp->state = CH_STATE_READY;
cp = (thread_t *)&ch.rlist.queue;
do {
cp = cp->queue.next;
} while (cp->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;
return tp;
}
/**
* @brief Puts the current thread to sleep into the specified state.
* @details The thread goes into a sleeping state. The possible
* @ref thread_states are defined into @p threads.h.
*
* @param[in] newstate the new thread state
*
* @sclass
*/
void chSchGoSleepS(tstate_t newstate) {
thread_t *otp = currp;
chDbgCheckClassS();
/* New state.*/
otp->state = newstate;
#if CH_CFG_TIME_QUANTUM > 0
/* The thread is renouncing its remaining time slices so it will have a new
time quantum when it will wakeup.*/
otp->ticks = (tslices_t)CH_CFG_TIME_QUANTUM;
#endif
/* Next thread in ready list becomes current.*/
currp = queue_fifo_remove(&ch.rlist.queue);
currp->state = CH_STATE_CURRENT;
/* Handling idle-enter hook.*/
if (currp->prio == IDLEPRIO) {
CH_CFG_IDLE_ENTER_HOOK();
}
/* Swap operation as tail call.*/
chSysSwitch(currp, otp);
}
/* /*
* Timeout wakeup callback. * Timeout wakeup callback.
*/ */
@ -340,7 +80,7 @@ static void wakeup(void *p) {
case CH_STATE_WTCOND: case CH_STATE_WTCOND:
#endif #endif
/* States requiring dequeuing.*/ /* States requiring dequeuing.*/
(void) queue_dequeue(tp); (void) ch_queue_dequeue(&tp->hdr.queue);
break; break;
default: default:
/* Any other state, nothing to do.*/ /* Any other state, nothing to do.*/
@ -351,6 +91,149 @@ static void wakeup(void *p) {
chSysUnlockFromISR(); chSysUnlockFromISR();
} }
/*===========================================================================*/
/* Module exported functions. */
/*===========================================================================*/
#if (CH_CFG_OPTIMIZE_SPEED == FALSE) || defined(__DOXYGEN__)
/**
* @brief Inserts a thread into a priority ordered queue.
* @note The insertion is done by scanning the list from the highest
* priority toward the lowest.
*
* @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 ch_sch_prio_insert(ch_queue_t *tp, ch_queue_t *qp) {
ch_queue_t *cp = qp;
do {
cp = cp->next;
} while ((cp != qp) &&
(((thread_t *)cp)->hdr.pqueue.prio >= ((thread_t *)tp)->hdr.pqueue.prio));
tp->next = cp;
tp->prev = cp->prev;
tp->prev->next = tp;
cp->prev = tp;
}
#endif /* CH_CFG_OPTIMIZE_SPEED */
/**
* @brief Scheduler initialization.
*
* @notapi
*/
void _scheduler_init(void) {
ch_pqueue_init(&ch.rlist.pqueue);
#if CH_CFG_USE_REGISTRY == TRUE
ch.rlist.newer = (thread_t *)&ch.rlist;
ch.rlist.older = (thread_t *)&ch.rlist;
#endif
}
/**
* @brief Inserts a thread in the Ready List placing it behind its peers.
* @details The thread is positioned behind all threads with higher or equal
* priority.
* @pre The thread must not be already inserted in any list through its
* @p next and @p prev or list corruption would occur.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
*
* @param[in] tp the thread to be made ready
* @return The thread pointer.
*
* @iclass
*/
thread_t *chSchReadyI(thread_t *tp) {
chDbgCheckClassI();
chDbgCheck(tp != NULL);
chDbgAssert((tp->state != CH_STATE_READY) &&
(tp->state != CH_STATE_FINAL),
"invalid state");
/* The thread is marked ready.*/
tp->state = CH_STATE_READY;
/* Insertion in the priority queue.*/
return (thread_t *)ch_pqueue_insert_behind(&ch.rlist.pqueue,
&tp->hdr.pqueue);
}
/**
* @brief Inserts a thread in the Ready List placing it ahead its peers.
* @details The thread is positioned ahead all threads with higher or equal
* priority.
* @pre The thread must not be already inserted in any list through its
* @p next and @p prev or list corruption would occur.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
*
* @param[in] tp the thread to be made ready
* @return The thread pointer.
*
* @iclass
*/
thread_t *chSchReadyAheadI(thread_t *tp) {
chDbgCheckClassI();
chDbgCheck(tp != NULL);
chDbgAssert((tp->state != CH_STATE_READY) &&
(tp->state != CH_STATE_FINAL),
"invalid state");
/* The thread is marked ready.*/
tp->state = CH_STATE_READY;
/* Insertion in the priority queue.*/
return (thread_t *)ch_pqueue_insert_ahead(&ch.rlist.pqueue,
&tp->hdr.pqueue);
}
/**
* @brief Puts the current thread to sleep into the specified state.
* @details The thread goes into a sleeping state. The possible
* @ref thread_states are defined into @p threads.h.
*
* @param[in] newstate the new thread state
*
* @sclass
*/
void chSchGoSleepS(tstate_t newstate) {
thread_t *otp = currp;
chDbgCheckClassS();
/* New state.*/
otp->state = newstate;
#if CH_CFG_TIME_QUANTUM > 0
/* The thread is renouncing its remaining time slices so it will have a new
time quantum when it will wakeup.*/
otp->ticks = (tslices_t)CH_CFG_TIME_QUANTUM;
#endif
/* Next thread in ready list becomes current.*/
currp = (thread_t *)ch_pqueue_remove_highest(&ch.rlist.pqueue);
currp->state = CH_STATE_CURRENT;
/* Handling idle-enter hook.*/
if (currp->hdr.pqueue.prio == IDLEPRIO) {
CH_CFG_IDLE_ENTER_HOOK();
}
/* Swap operation as tail call.*/
chSysSwitch(currp, otp);
}
/** /**
* @brief Puts the current thread to sleep into the specified state with * @brief Puts the current thread to sleep into the specified state with
* timeout specification. * timeout specification.
@ -414,8 +297,8 @@ void chSchWakeupS(thread_t *ntp, msg_t msg) {
chDbgCheckClassS(); chDbgCheckClassS();
chDbgAssert((ch.rlist.queue.next == (thread_t *)&ch.rlist.queue) || chDbgAssert((ch.rlist.pqueue.next == &ch.rlist.pqueue) ||
(ch.rlist.current->prio >= ch.rlist.queue.next->prio), (ch.rlist.current->hdr.pqueue.prio >= ch.rlist.pqueue.next->prio),
"priority order violation"); "priority order violation");
/* Storing the message to be retrieved by the target thread when it will /* Storing the message to be retrieved by the target thread when it will
@ -426,14 +309,14 @@ void chSchWakeupS(thread_t *ntp, msg_t msg) {
one then it is just inserted in the ready list else it made one then it is just inserted in the ready list else it made
running immediately and the invoking thread goes in the ready running immediately and the invoking thread goes in the ready
list instead.*/ list instead.*/
if (ntp->prio <= otp->prio) { if (ntp->hdr.pqueue.prio <= otp->hdr.pqueue.prio) {
(void) chSchReadyI(ntp); (void) chSchReadyI(ntp);
} }
else { else {
otp = chSchReadyAheadI(otp); otp = chSchReadyAheadI(otp);
/* Handling idle-leave hook.*/ /* Handling idle-leave hook.*/
if (otp->prio == IDLEPRIO) { if (otp->hdr.pqueue.prio == IDLEPRIO) {
CH_CFG_IDLE_LEAVE_HOOK(); CH_CFG_IDLE_LEAVE_HOOK();
} }
@ -477,8 +360,8 @@ void chSchRescheduleS(void) {
* @special * @special
*/ */
bool chSchIsPreemptionRequired(void) { bool chSchIsPreemptionRequired(void) {
tprio_t p1 = firstprio(&ch.rlist.queue); tprio_t p1 = firstprio(&ch.rlist.pqueue);
tprio_t p2 = currp->prio; tprio_t p2 = currp->hdr.pqueue.prio;
#if CH_CFG_TIME_QUANTUM > 0 #if CH_CFG_TIME_QUANTUM > 0
/* If the running thread has not reached its time quantum, reschedule only /* If the running thread has not reached its time quantum, reschedule only
@ -508,11 +391,11 @@ void chSchDoRescheduleBehind(void) {
thread_t *otp = currp; thread_t *otp = currp;
/* Picks the first thread from the ready queue and makes it current.*/ /* Picks the first thread from the ready queue and makes it current.*/
currp = queue_fifo_remove(&ch.rlist.queue); currp = (thread_t *)ch_pqueue_remove_highest(&ch.rlist.pqueue);
currp->state = CH_STATE_CURRENT; currp->state = CH_STATE_CURRENT;
/* Handling idle-leave hook.*/ /* Handling idle-leave hook.*/
if (otp->prio == IDLEPRIO) { if (otp->hdr.pqueue.prio == IDLEPRIO) {
CH_CFG_IDLE_LEAVE_HOOK(); CH_CFG_IDLE_LEAVE_HOOK();
} }
@ -541,11 +424,11 @@ void chSchDoRescheduleAhead(void) {
thread_t *otp = currp; thread_t *otp = currp;
/* Picks the first thread from the ready queue and makes it current.*/ /* Picks the first thread from the ready queue and makes it current.*/
currp = queue_fifo_remove(&ch.rlist.queue); currp = (thread_t *)ch_pqueue_remove_highest(&ch.rlist.pqueue);
currp->state = CH_STATE_CURRENT; currp->state = CH_STATE_CURRENT;
/* Handling idle-leave hook.*/ /* Handling idle-leave hook.*/
if (otp->prio == IDLEPRIO) { if (otp->hdr.pqueue.prio == IDLEPRIO) {
CH_CFG_IDLE_LEAVE_HOOK(); CH_CFG_IDLE_LEAVE_HOOK();
} }
@ -571,11 +454,11 @@ void chSchDoReschedule(void) {
thread_t *otp = currp; thread_t *otp = currp;
/* Picks the first thread from the ready queue and makes it current.*/ /* Picks the first thread from the ready queue and makes it current.*/
currp = queue_fifo_remove(&ch.rlist.queue); currp = (thread_t *)ch_pqueue_remove_highest(&ch.rlist.pqueue);
currp->state = CH_STATE_CURRENT; currp->state = CH_STATE_CURRENT;
/* Handling idle-leave hook.*/ /* Handling idle-leave hook.*/
if (otp->prio == IDLEPRIO) { if (otp->hdr.pqueue.prio == IDLEPRIO) {
CH_CFG_IDLE_LEAVE_HOOK(); CH_CFG_IDLE_LEAVE_HOOK();
} }

View File

@ -76,9 +76,9 @@
/*===========================================================================*/ /*===========================================================================*/
#if CH_CFG_USE_SEMAPHORES_PRIORITY == TRUE #if CH_CFG_USE_SEMAPHORES_PRIORITY == TRUE
#define sem_insert(tp, qp) queue_prio_insert(tp, qp) #define sem_insert(tp, qp) ch_sch_prio_insert(&tp->hdr.pqueue, qp)
#else #else
#define sem_insert(tp, qp) queue_insert(tp, qp) #define sem_insert(tp, qp) ch_queue_insert(&tp->hdr.queue, qp)
#endif #endif
/*===========================================================================*/ /*===========================================================================*/
@ -98,7 +98,7 @@ void chSemObjectInit(semaphore_t *sp, cnt_t n) {
chDbgCheck((sp != NULL) && (n >= (cnt_t)0)); chDbgCheck((sp != NULL) && (n >= (cnt_t)0));
queue_init(&sp->queue); ch_queue_init(&sp->queue);
sp->cnt = n; sp->cnt = n;
} }
@ -144,13 +144,13 @@ void chSemResetWithMessageI(semaphore_t *sp, cnt_t n, msg_t msg) {
chDbgCheckClassI(); chDbgCheckClassI();
chDbgCheck((sp != NULL) && (n >= (cnt_t)0)); chDbgCheck((sp != NULL) && (n >= (cnt_t)0));
chDbgAssert(((sp->cnt >= (cnt_t)0) && queue_isempty(&sp->queue)) || chDbgAssert(((sp->cnt >= (cnt_t)0) && ch_queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && queue_notempty(&sp->queue)), ((sp->cnt < (cnt_t)0) && ch_queue_notempty(&sp->queue)),
"inconsistent semaphore"); "inconsistent semaphore");
sp->cnt = n; sp->cnt = n;
while (queue_notempty(&sp->queue)) { while (ch_queue_notempty(&sp->queue)) {
chSchReadyI(queue_lifo_remove(&sp->queue))->u.rdymsg = msg; chSchReadyI((thread_t *)ch_queue_lifo_remove(&sp->queue))->u.rdymsg = msg;
} }
} }
@ -192,8 +192,8 @@ msg_t chSemWaitS(semaphore_t *sp) {
chDbgCheckClassS(); chDbgCheckClassS();
chDbgCheck(sp != NULL); chDbgCheck(sp != NULL);
chDbgAssert(((sp->cnt >= (cnt_t)0) && queue_isempty(&sp->queue)) || chDbgAssert(((sp->cnt >= (cnt_t)0) && ch_queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && queue_notempty(&sp->queue)), ((sp->cnt < (cnt_t)0) && ch_queue_notempty(&sp->queue)),
"inconsistent semaphore"); "inconsistent semaphore");
if (--sp->cnt < (cnt_t)0) { if (--sp->cnt < (cnt_t)0) {
@ -259,8 +259,8 @@ msg_t chSemWaitTimeoutS(semaphore_t *sp, sysinterval_t timeout) {
chDbgCheckClassS(); chDbgCheckClassS();
chDbgCheck(sp != NULL); chDbgCheck(sp != NULL);
chDbgAssert(((sp->cnt >= (cnt_t)0) && queue_isempty(&sp->queue)) || chDbgAssert(((sp->cnt >= (cnt_t)0) && ch_queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && queue_notempty(&sp->queue)), ((sp->cnt < (cnt_t)0) && ch_queue_notempty(&sp->queue)),
"inconsistent semaphore"); "inconsistent semaphore");
if (--sp->cnt < (cnt_t)0) { if (--sp->cnt < (cnt_t)0) {
@ -290,11 +290,11 @@ void chSemSignal(semaphore_t *sp) {
chDbgCheck(sp != NULL); chDbgCheck(sp != NULL);
chSysLock(); chSysLock();
chDbgAssert(((sp->cnt >= (cnt_t)0) && queue_isempty(&sp->queue)) || chDbgAssert(((sp->cnt >= (cnt_t)0) && ch_queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && queue_notempty(&sp->queue)), ((sp->cnt < (cnt_t)0) && ch_queue_notempty(&sp->queue)),
"inconsistent semaphore"); "inconsistent semaphore");
if (++sp->cnt <= (cnt_t)0) { 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(); chSysUnlock();
} }
@ -314,14 +314,14 @@ void chSemSignalI(semaphore_t *sp) {
chDbgCheckClassI(); chDbgCheckClassI();
chDbgCheck(sp != NULL); chDbgCheck(sp != NULL);
chDbgAssert(((sp->cnt >= (cnt_t)0) && queue_isempty(&sp->queue)) || chDbgAssert(((sp->cnt >= (cnt_t)0) && ch_queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && queue_notempty(&sp->queue)), ((sp->cnt < (cnt_t)0) && ch_queue_notempty(&sp->queue)),
"inconsistent semaphore"); "inconsistent semaphore");
if (++sp->cnt <= (cnt_t)0) { if (++sp->cnt <= (cnt_t)0) {
/* Note, it is done this way in order to allow a tail call on /* Note, it is done this way in order to allow a tail call on
chSchReadyI().*/ 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; tp->u.rdymsg = MSG_OK;
(void) chSchReadyI(tp); (void) chSchReadyI(tp);
} }
@ -344,13 +344,13 @@ void chSemAddCounterI(semaphore_t *sp, cnt_t n) {
chDbgCheckClassI(); chDbgCheckClassI();
chDbgCheck((sp != NULL) && (n > (cnt_t)0)); chDbgCheck((sp != NULL) && (n > (cnt_t)0));
chDbgAssert(((sp->cnt >= (cnt_t)0) && queue_isempty(&sp->queue)) || chDbgAssert(((sp->cnt >= (cnt_t)0) && ch_queue_isempty(&sp->queue)) ||
((sp->cnt < (cnt_t)0) && queue_notempty(&sp->queue)), ((sp->cnt < (cnt_t)0) && ch_queue_notempty(&sp->queue)),
"inconsistent semaphore"); "inconsistent semaphore");
while (n > (cnt_t)0) { while (n > (cnt_t)0) {
if (++sp->cnt <= (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--; n--;
} }
@ -375,14 +375,14 @@ msg_t chSemSignalWait(semaphore_t *sps, semaphore_t *spw) {
chDbgCheck((sps != NULL) && (spw != NULL)); chDbgCheck((sps != NULL) && (spw != NULL));
chSysLock(); chSysLock();
chDbgAssert(((sps->cnt >= (cnt_t)0) && queue_isempty(&sps->queue)) || chDbgAssert(((sps->cnt >= (cnt_t)0) && ch_queue_isempty(&sps->queue)) ||
((sps->cnt < (cnt_t)0) && queue_notempty(&sps->queue)), ((sps->cnt < (cnt_t)0) && ch_queue_notempty(&sps->queue)),
"inconsistent semaphore"); "inconsistent semaphore");
chDbgAssert(((spw->cnt >= (cnt_t)0) && queue_isempty(&spw->queue)) || chDbgAssert(((spw->cnt >= (cnt_t)0) && ch_queue_isempty(&spw->queue)) ||
((spw->cnt < (cnt_t)0) && queue_notempty(&spw->queue)), ((spw->cnt < (cnt_t)0) && ch_queue_notempty(&spw->queue)),
"inconsistent semaphore"); "inconsistent semaphore");
if (++sps->cnt <= (cnt_t)0) { 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) { if (--spw->cnt < (cnt_t)0) {
thread_t *ctp = currp; thread_t *ctp = currp;

View File

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

View File

@ -87,34 +87,34 @@
*/ */
thread_t *_thread_init(thread_t *tp, const char *name, tprio_t prio) { thread_t *_thread_init(thread_t *tp, const char *name, tprio_t prio) {
tp->prio = prio; tp->hdr.pqueue.prio = prio;
tp->state = CH_STATE_WTSTART; tp->state = CH_STATE_WTSTART;
tp->flags = CH_FLAG_MODE_STATIC; tp->flags = CH_FLAG_MODE_STATIC;
#if CH_CFG_TIME_QUANTUM > 0 #if CH_CFG_TIME_QUANTUM > 0
tp->ticks = (tslices_t)CH_CFG_TIME_QUANTUM; tp->ticks = (tslices_t)CH_CFG_TIME_QUANTUM;
#endif #endif
#if CH_CFG_USE_MUTEXES == TRUE #if CH_CFG_USE_MUTEXES == TRUE
tp->realprio = prio; tp->realprio = prio;
tp->mtxlist = NULL; tp->mtxlist = NULL;
#endif #endif
#if CH_CFG_USE_EVENTS == TRUE #if CH_CFG_USE_EVENTS == TRUE
tp->epending = (eventmask_t)0; tp->epending = (eventmask_t)0;
#endif #endif
#if CH_DBG_THREADS_PROFILING == TRUE #if CH_DBG_THREADS_PROFILING == TRUE
tp->time = (systime_t)0; tp->time = (systime_t)0;
#endif #endif
#if CH_CFG_USE_REGISTRY == TRUE #if CH_CFG_USE_REGISTRY == TRUE
tp->refs = (trefs_t)1; tp->refs = (trefs_t)1;
tp->name = name; tp->name = name;
REG_INSERT(tp); REG_INSERT(tp);
#else #else
(void)name; (void)name;
#endif #endif
#if CH_CFG_USE_WAITEXIT == TRUE #if CH_CFG_USE_WAITEXIT == TRUE
list_init(&tp->waiting); ch_list_init(&tp->waiting);
#endif #endif
#if CH_CFG_USE_MESSAGES == TRUE #if CH_CFG_USE_MESSAGES == TRUE
queue_init(&tp->msgqueue); ch_queue_init(&tp->msgqueue);
#endif #endif
#if CH_DBG_STATISTICS == TRUE #if CH_DBG_STATISTICS == TRUE
chTMObjectInit(&tp->stats); chTMObjectInit(&tp->stats);
@ -509,8 +509,8 @@ void chThdExitS(msg_t msg) {
#if CH_CFG_USE_WAITEXIT == TRUE #if CH_CFG_USE_WAITEXIT == TRUE
/* Waking up any waiting thread.*/ /* Waking up any waiting thread.*/
while (list_notempty(&tp->waiting)) { while (ch_list_notempty(&tp->waiting)) {
(void) chSchReadyI(list_remove(&tp->waiting)); (void) chSchReadyI((thread_t *)ch_list_pop(&tp->waiting));
} }
#endif #endif
@ -568,7 +568,7 @@ msg_t chThdWait(thread_t *tp) {
#endif #endif
if (tp->state != CH_STATE_FINAL) { if (tp->state != CH_STATE_FINAL) {
list_insert(currp, &tp->waiting); ch_list_push(&currp->hdr.list, &tp->waiting);
chSchGoSleepS(CH_STATE_WTEXIT); chSchGoSleepS(CH_STATE_WTEXIT);
} }
msg = tp->u.exitcode; msg = tp->u.exitcode;
@ -603,13 +603,14 @@ tprio_t chThdSetPriority(tprio_t newprio) {
chSysLock(); chSysLock();
#if CH_CFG_USE_MUTEXES == TRUE #if CH_CFG_USE_MUTEXES == TRUE
oldprio = currp->realprio; oldprio = currp->realprio;
if ((currp->prio == currp->realprio) || (newprio > currp->prio)) { if ((currp->hdr.pqueue.prio == currp->realprio) ||
currp->prio = newprio; (newprio > currp->hdr.pqueue.prio)) {
currp->hdr.pqueue.prio = newprio;
} }
currp->realprio = newprio; currp->realprio = newprio;
#else #else
oldprio = currp->prio; oldprio = currp->hdr.pqueue.prio;
currp->prio = newprio; currp->hdr.pqueue.prio = newprio;
#endif #endif
chSchRescheduleS(); chSchRescheduleS();
chSysUnlock(); chSysUnlock();
@ -867,7 +868,7 @@ msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout) {
return MSG_TIMEOUT; return MSG_TIMEOUT;
} }
queue_insert(currp, tqp); ch_queue_insert(&currp->hdr.queue, &tqp->queue);
return chSchGoSleepTimeoutS(CH_STATE_QUEUED, timeout); return chSchGoSleepTimeoutS(CH_STATE_QUEUED, timeout);
} }
@ -883,7 +884,7 @@ msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout) {
*/ */
void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg) { void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg) {
if (queue_notempty(tqp)) { if (ch_queue_notempty(&tqp->queue)) {
chThdDoDequeueNextI(tqp, msg); chThdDoDequeueNextI(tqp, msg);
} }
} }
@ -898,7 +899,7 @@ void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg) {
*/ */
void chThdDequeueAllI(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); chThdDoDequeueNextI(tqp, msg);
} }
} }

View File

@ -32,45 +32,6 @@
/* Module local definitions. */ /* 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. */ /* Module exported variables. */
/*===========================================================================*/ /*===========================================================================*/
@ -87,7 +48,58 @@
/* 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.
*
* @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);
}
/** /**
* @brief Delta list compression. * @brief Delta list compression.
* *
@ -98,21 +110,21 @@
*/ */
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) {
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 /* The loop is bounded because the delta list header has the delta field
set to (sysinterval_t)-1 which is larger than all deltas.*/ set to (sysinterval_t)-1 which is larger than all deltas.*/
while (vtp->delta < deltanow) { while (dlp->delta < deltanow) {
deltanow -= vtp->delta; deltanow -= dlp->delta;
vtp->delta = (sysinterval_t)0; dlp->delta = (sysinterval_t)0;
vtp = vtp->next; dlp = dlp->next;
} }
vtlp->lasttime = vtlp->lasttime + deltanow; vtlp->lasttime = vtlp->lasttime + deltanow;
/* Adjusting next timer in the list, if any.*/ /* Adjusting next timer in the list, if any.*/
if (is_timer(vtlp, vtp)) { if (is_timer(&vtlp->dlist, dlp)) {
vtp->delta -= deltanow; dlp->delta -= deltanow;
} }
} }
#endif #endif
@ -129,9 +141,9 @@ static void vt_list_compress(virtual_timers_list_t *vtlp,
*/ */
void _vt_init(void) { void _vt_init(void) {
ch.vtlist.next = (virtual_timer_t *)&ch.vtlist; ch.vtlist.dlist.next = &ch.vtlist.dlist;
ch.vtlist.prev = (virtual_timer_t *)&ch.vtlist; ch.vtlist.dlist.prev = &ch.vtlist.dlist;
ch.vtlist.delta = (sysinterval_t)-1; ch.vtlist.dlist.delta = (sysinterval_t)-1;
#if CH_CFG_ST_TIMEDELTA == 0 #if CH_CFG_ST_TIMEDELTA == 0
ch.vtlist.systime = (systime_t)0; ch.vtlist.systime = (systime_t)0;
#else /* CH_CFG_ST_TIMEDELTA > 0 */ #else /* CH_CFG_ST_TIMEDELTA > 0 */
@ -164,7 +176,7 @@ void _vt_init(void) {
void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay, void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay,
vtfunc_t vtfunc, void *par) { vtfunc_t vtfunc, void *par) {
virtual_timers_list_t *vtlp = &ch.vtlist; virtual_timers_list_t *vtlp = &ch.vtlist;
virtual_timer_t *p; delta_list_t *dlp;
sysinterval_t delta; sysinterval_t delta;
chDbgCheckClassI(); chDbgCheckClassI();
@ -185,16 +197,16 @@ void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay,
} }
/* Special case where the timers list is empty.*/ /* 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 /* 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;
vtlp->next = vtp; vtlp->dlist.next = &vtp->dlist;
vtlp->prev = vtp; vtlp->dlist.prev = &vtp->dlist;
vtp->next = (virtual_timer_t *)vtlp; vtp->dlist.next = &vtlp->dlist;
vtp->prev = (virtual_timer_t *)vtlp; vtp->dlist.prev = &vtlp->dlist;
vtp->delta = delay; vtp->dlist.delta = 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.*/
@ -220,7 +232,7 @@ void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay,
vt_list_compress(vtlp, deltanow); vt_list_compress(vtlp, deltanow);
delta -= deltanow; delta -= deltanow;
} }
else if (delta < vtlp->next->delta) { else if (delta < vtlp->dlist.next->delta) {
sysinterval_t deadline_delta; sysinterval_t deadline_delta;
/* A small delay that will become the first element in the delta list /* A small delay that will become the first element in the delta list
@ -242,28 +254,28 @@ void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay,
/* The delta list is scanned in order to find the correct position for /* The delta list is scanned in order to find the correct position for
this timer. */ this timer. */
p = vtlp->next; dlp = vtlp->dlist.next;
while (p->delta < delta) { while (dlp->delta < delta) {
/* Debug assert if the timer is already in the list.*/ /* 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; delta -= dlp->delta;
p = p->next; dlp = dlp->next;
} }
/* The timer is inserted in the delta list.*/ /* The timer is inserted in the delta list.*/
vtp->next = p; vtp->dlist.next = dlp;
vtp->prev = vtp->next->prev; vtp->dlist.prev = vtp->dlist.next->prev;
vtp->prev->next = vtp; vtp->dlist.prev->next = &vtp->dlist;
p->prev = vtp; dlp->prev = &vtp->dlist;
vtp->delta = delta; vtp->dlist.delta = delta;
/* Calculate new delta for the following entry.*/ /* 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 /* Special case when the timer is in last position in the list, the
value in the header must be restored.*/ value in the header must be restored.*/
vtlp->delta = (sysinterval_t)-1; vtlp->dlist.delta = (sysinterval_t)-1;
} }
/** /**
@ -284,52 +296,52 @@ void chVTDoResetI(virtual_timer_t *vtp) {
#if CH_CFG_ST_TIMEDELTA == 0 #if CH_CFG_ST_TIMEDELTA == 0
/* The delta of the timer is added to the next timer.*/ /* The delta of the timer is added to the next timer.*/
vtp->next->delta += vtp->delta; vtp->dlist.next->delta += vtp->dlist.delta;
/* Removing the element from the delta list.*/ /* Removing the element from the delta list.*/
vtp->prev->next = vtp->next; vtp->dlist.prev->next = vtp->dlist.next;
vtp->next->prev = vtp->prev; vtp->dlist.next->prev = vtp->dlist.prev;
vtp->func = NULL; vtp->func = NULL;
/* The above code changes the value in the header when the removed element /* The above code changes the value in the header when the removed element
is the last of the list, restoring it.*/ is the last of the list, restoring it.*/
vtlp->delta = (sysinterval_t)-1; vtlp->dlist.delta = (sysinterval_t)-1;
#else /* CH_CFG_ST_TIMEDELTA > 0 */ #else /* CH_CFG_ST_TIMEDELTA > 0 */
sysinterval_t nowdelta, delta; sysinterval_t nowdelta, delta;
/* 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, vtp)) { if (!is_first_timer(&vtlp->dlist, &vtp->dlist)) {
/* Removing the element from the delta list.*/ /* Removing the element from the delta list.*/
vtp->prev->next = vtp->next; vtp->dlist.prev->next = vtp->dlist.next;
vtp->next->prev = vtp->prev; vtp->dlist.next->prev = vtp->dlist.prev;
vtp->func = NULL; vtp->func = NULL;
/* 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, vtp->next)) if (is_timer(&vtlp->dlist, vtp->dlist.next))
vtp->next->delta += vtp->delta; vtp->dlist.next->delta += vtp->dlist.delta;
return; return;
} }
/* Removing the first timer from the list.*/ /* Removing the first timer from the list.*/
vtlp->next = vtp->next; vtlp->dlist.next = vtp->dlist.next;
vtlp->next->prev = (virtual_timer_t *)vtlp; vtlp->dlist.next->prev = &vtlp->dlist;
vtp->func = NULL; vtp->func = 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)) { if (is_vtlist_empty(&vtlp->dlist)) {
port_timer_stop_alarm(); port_timer_stop_alarm();
return; return;
} }
/* The delta of the removed timer is added to the new first timer.*/ /* 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 /* If the new first timer has a delta of zero then the alarm is not
modified, the already programmed alarm will serve it.*/ modified, the already programmed alarm will serve it.*/
/* if (vtlp->next->delta == 0) { /* if (vtlp->dlist.next->delta == 0) {
return; return;
}*/ }*/
@ -338,12 +350,12 @@ void chVTDoResetI(virtual_timer_t *vtp) {
/* If the current time surpassed the time of the next element in list /* If the current time surpassed the time of the next element in list
then the event interrupt is already pending, just return.*/ then the event interrupt is already pending, just return.*/
if (nowdelta >= vtlp->next->delta) { if (nowdelta >= vtlp->dlist.next->delta) {
return; return;
} }
/* Distance from the next scheduled event and now.*/ /* 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 /* Making sure to not schedule an event closer than CH_CFG_ST_TIMEDELTA
ticks from now.*/ ticks from now.*/
@ -379,30 +391,30 @@ void chVTDoTickI(void) {
#if CH_CFG_ST_TIMEDELTA == 0 #if CH_CFG_ST_TIMEDELTA == 0
vtlp->systime++; vtlp->systime++;
if (!is_vtlist_empty(vtlp)) { if (!is_vtlist_empty(&vtlp->dlist)) {
/* The list is not empty, processing elements on top.*/ /* The list is not empty, processing elements on top.*/
--vtlp->next->delta; --vtlp->dlist.next->delta;
while (vtlp->next->delta == (sysinterval_t)0) { while (vtlp->dlist.next->delta == (sysinterval_t)0) {
virtual_timer_t *vtp; virtual_timer_t *vtp;
vtfunc_t fn; vtfunc_t fn;
vtp = vtlp->next; vtp = (virtual_timer_t *)vtlp->dlist.next;
fn = vtp->func; fn = vtp->func;
vtp->func = NULL; vtp->func = NULL;
vtp->next->prev = (virtual_timer_t *)vtlp; vtp->dlist.next->prev = &vtlp->dlist;
vtlp->next = vtp->next; vtlp->dlist.next = vtp->dlist.next;
chSysUnlockFromISR(); chSysUnlockFromISR();
fn(vtp->par); fn(vtp->par);
chSysLockFromISR(); chSysLockFromISR();
} }
} }
#else /* CH_CFG_ST_TIMEDELTA > 0 */ #else /* CH_CFG_ST_TIMEDELTA > 0 */
virtual_timer_t *vtp; delta_list_t *dlp;
systime_t now; systime_t now;
sysinterval_t delta, nowdelta; sysinterval_t delta, nowdelta;
/* Looping through timers.*/ /* Looping through timers.*/
vtp = vtlp->next; dlp = vtlp->dlist.next;
while (true) { while (true) {
/* Getting the system time as reference.*/ /* Getting the system time as reference.*/
@ -410,27 +422,32 @@ void chVTDoTickI(void) {
nowdelta = chTimeDiffX(vtlp->lasttime, now); nowdelta = chTimeDiffX(vtlp->lasttime, now);
/* The list scan is limited by the timers header having /* 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.*/ greater than all deltas.*/
if (nowdelta < vtp->delta) { if (nowdelta < dlp->delta) {
break; break;
} }
/* Consuming all timers between "vtp->lasttime" and now.*/ /* Consuming all timers between "vtp->lasttime" and now.*/
do { do {
vtfunc_t fn; vtfunc_t fn;
virtual_timer_t *vtp = (virtual_timer_t *)dlp;
/* The "last time" becomes this timer's expiration time.*/ /* The "last time" becomes this timer's expiration time.*/
vtlp->lasttime += vtp->delta; vtlp->lasttime += dlp->delta;
nowdelta -= vtp->delta; nowdelta -= dlp->delta;
vtp->next->prev = (virtual_timer_t *)vtlp; /* Removing the timer from the list.*/
vtlp->next = vtp->next; 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; fn = vtp->func;
vtp->func = NULL; vtp->func = 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)) { if (is_vtlist_empty(&vtlp->dlist)) {
port_timer_stop_alarm(); port_timer_stop_alarm();
} }
@ -440,23 +457,23 @@ void chVTDoTickI(void) {
chSysLockFromISR(); chSysLockFromISR();
/* Next element in the list.*/ /* 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 the list is empty, nothing else to do.*/
if (is_vtlist_empty(vtlp)) { if (is_vtlist_empty(&vtlp->dlist)) {
return; return;
} }
/* The "unprocessed nowdelta" time slice is added to "last time" /* The "unprocessed nowdelta" time slice is added to "last time"
and subtracted to next timer's delta.*/ and subtracted to next timer's delta.*/
vtlp->lasttime += nowdelta; vtlp->lasttime += nowdelta;
vtlp->next->delta -= nowdelta; vtlp->dlist.next->delta -= nowdelta;
/* Recalculating the next alarm time.*/ /* 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) { if (delta < (sysinterval_t)CH_CFG_ST_TIMEDELTA) {
delta = (sysinterval_t)CH_CFG_ST_TIMEDELTA; delta = (sysinterval_t)CH_CFG_ST_TIMEDELTA;
} }

View File

@ -75,6 +75,8 @@
*** 20.3.3 *** *** 20.3.3 ***
- FIX: Fixed GCC 10 causes warning in factory module (bug #1139). - FIX: Fixed GCC 10 causes warning in factory module (bug #1139).
- FIX: Fixed C strict aliasing rules violation causes test cases to fail
(bug #1138).
- FIX: Fixed STM32H7xx Missing CRC RCC macros (bug #1137). - FIX: Fixed STM32H7xx Missing CRC RCC macros (bug #1137).
- FIX: Fixed STM32L0x wrong ISR names for USART 4 and 5 (bug #1136). - FIX: Fixed STM32L0x wrong ISR names for USART 4 and 5 (bug #1136).
- FIX: Fixed OTG_FS error on STM32H7 (bug #1135). - FIX: Fixed OTG_FS error on STM32H7 (bug #1135).

View File

@ -1064,7 +1064,7 @@ test_assert(chThdGetPriorityX() == prio, "unexpected priority level");]]></value
</tags> </tags>
<code> <code>
<value><![CDATA[prio = chThdGetPriorityX(); <value><![CDATA[prio = chThdGetPriorityX();
chThdGetSelfX()->prio += 2; chThdGetSelfX()->hdr.pqueue.prio += 2;
test_assert(chThdGetPriorityX() == prio + 2, "unexpected priority level");]]></value> test_assert(chThdGetPriorityX() == prio + 2, "unexpected priority level");]]></value>
</code> </code>
</step> </step>
@ -1078,7 +1078,7 @@ test_assert(chThdGetPriorityX() == prio + 2, "unexpected priority level");]]></v
<code> <code>
<value><![CDATA[p1 = chThdSetPriority(prio + 1); <value><![CDATA[p1 = chThdSetPriority(prio + 1);
test_assert(p1 == prio, "unexpected returned priority level"); test_assert(p1 == prio, "unexpected returned priority level");
test_assert(chThdGetSelfX()->prio == prio + 2, "unexpected priority level"); test_assert(chThdGetSelfX()->hdr.pqueue.prio == prio + 2, "unexpected priority level");
test_assert(chThdGetSelfX()->realprio == prio + 1, "unexpected returned real priority level");]]></value> test_assert(chThdGetSelfX()->realprio == prio + 1, "unexpected returned real priority level");]]></value>
</code> </code>
</step> </step>
@ -1092,7 +1092,7 @@ test_assert(chThdGetSelfX()->realprio == prio + 1, "unexpected returned real pri
<code> <code>
<value><![CDATA[p1 = chThdSetPriority(prio + 3); <value><![CDATA[p1 = chThdSetPriority(prio + 3);
test_assert(p1 == prio + 1, "unexpected returned priority level"); test_assert(p1 == prio + 1, "unexpected returned priority level");
test_assert(chThdGetSelfX()->prio == prio + 3, "unexpected priority level"); test_assert(chThdGetSelfX()->hdr.pqueue.prio == prio + 3, "unexpected priority level");
test_assert(chThdGetSelfX()->realprio == prio + 3, "unexpected real priority level");]]></value> test_assert(chThdGetSelfX()->realprio == prio + 3, "unexpected real priority level");]]></value>
</code> </code>
</step> </step>
@ -1105,7 +1105,7 @@ test_assert(chThdGetSelfX()->realprio == prio + 3, "unexpected real priority lev
</tags> </tags>
<code> <code>
<value><![CDATA[chSysLock(); <value><![CDATA[chSysLock();
chThdGetSelfX()->prio = prio; chThdGetSelfX()->hdr.pqueue.prio = prio;
chThdGetSelfX()->realprio = prio; chThdGetSelfX()->realprio = prio;
chSysUnlock();]]></value> chSysUnlock();]]></value>
</code> </code>
@ -1407,7 +1407,7 @@ msg_t msg;]]></value>
<code> <code>
<value><![CDATA[msg = chSemWaitTimeout(&sem1, TIME_IMMEDIATE); <value><![CDATA[msg = chSemWaitTimeout(&sem1, TIME_IMMEDIATE);
test_assert(msg == MSG_TIMEOUT, "wrong wake-up message"); 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");]]></value> test_assert(sem1.cnt == 0, "counter not zero");]]></value>
</code> </code>
</step> </step>
@ -1424,7 +1424,7 @@ test_assert(sem1.cnt == 0, "counter not zero");]]></value>
msg = chSemWaitTimeout(&sem1, TIME_MS2I(500)); msg = chSemWaitTimeout(&sem1, TIME_MS2I(500));
test_wait_threads(); test_wait_threads();
test_assert(msg == MSG_OK, "wrong wake-up message"); 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");]]></value> test_assert(sem1.cnt == 0, "counter not zero");]]></value>
</code> </code>
</step> </step>
@ -1441,7 +1441,7 @@ for (i = 0; i < 5; i++) {
test_emit_token('A' + i); test_emit_token('A' + i);
msg = chSemWaitTimeout(&sem1, TIME_MS2I(50)); msg = chSemWaitTimeout(&sem1, TIME_MS2I(50));
test_assert(msg == MSG_TIMEOUT, "wrong wake-up message"); 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(sem1.cnt == 0, "counter not zero");
} }
test_assert_sequence("ABCDE", "invalid sequence"); test_assert_sequence("ABCDE", "invalid sequence");
@ -1546,7 +1546,7 @@ test_assert_sequence("A", "invalid sequence");]]></value>
</tags> </tags>
<code> <code>
<value><![CDATA[chSemSignalWait(&sem1, &sem1); <value><![CDATA[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");]]></value> test_assert(sem1.cnt == 0, "counter not zero");]]></value>
</code> </code>
</step> </step>
@ -1559,7 +1559,7 @@ test_assert(sem1.cnt == 0, "counter not zero");]]></value>
</tags> </tags>
<code> <code>
<value><![CDATA[chSemSignalWait(&sem1, &sem1); <value><![CDATA[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");]]></value> test_assert(sem1.cnt == 0, "counter not zero");]]></value>
</code> </code>
</step> </step>
@ -2251,7 +2251,7 @@ test_assert(!b, "not locked");]]></value>
<code> <code>
<value><![CDATA[chMtxUnlock(&m1); <value><![CDATA[chMtxUnlock(&m1);
test_assert(m1.owner == NULL, "still owned"); test_assert(m1.owner == NULL, "still owned");
test_assert(queue_isempty(&m1.queue), "queue not empty");]]></value> test_assert(ch_queue_isempty(&m1.queue), "queue not empty");]]></value>
</code> </code>
</step> </step>
<step> <step>
@ -2280,7 +2280,7 @@ test_assert(!b, "not locked");
chMtxUnlockAll(); chMtxUnlockAll();
test_assert(m1.owner == NULL, "still owned"); test_assert(m1.owner == NULL, "still owned");
test_assert(queue_isempty(&m1.queue), "queue not empty");]]></value> test_assert(ch_queue_isempty(&m1.queue), "queue not empty");]]></value>
</code> </code>
</step> </step>
<step> <step>
@ -2376,7 +2376,7 @@ test_assert(m1.owner != NULL, "not owned");]]></value>
<code> <code>
<value><![CDATA[chMtxUnlock(&m1); <value><![CDATA[chMtxUnlock(&m1);
test_assert(m1.owner == NULL, "still owned"); test_assert(m1.owner == NULL, "still owned");
test_assert(queue_isempty(&m1.queue), "queue not empty");]]></value> test_assert(ch_queue_isempty(&m1.queue), "queue not empty");]]></value>
</code> </code>
</step> </step>
<step> <step>
@ -2409,7 +2409,7 @@ chSysLock();
chMtxUnlockAllS(); chMtxUnlockAllS();
chSysUnlock(); chSysUnlock();
test_assert(m1.owner == NULL, "still owned"); 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_assert(m1.cnt == 0, "invalid recursion counter");]]></value> test_assert(m1.cnt == 0, "invalid recursion counter");]]></value>
</code> </code>
</step> </step>
@ -2430,7 +2430,7 @@ test_assert(m1.owner != NULL, "not owned");
test_assert(m1.cnt == 2, "invalid recursion counter"); test_assert(m1.cnt == 2, "invalid recursion counter");
chMtxUnlockAll(); chMtxUnlockAll();
test_assert(m1.owner == NULL, "still owned"); 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_assert(m1.cnt == 0, "invalid recursion counter");]]></value> test_assert(m1.cnt == 0, "invalid recursion counter");]]></value>
</code> </code>
</step> </step>

View File

@ -294,7 +294,7 @@ static void rt_test_004_004_execute(void) {
test_set_step(1); test_set_step(1);
{ {
prio = chThdGetPriorityX(); prio = chThdGetPriorityX();
chThdGetSelfX()->prio += 2; chThdGetSelfX()->hdr.pqueue.prio += 2;
test_assert(chThdGetPriorityX() == prio + 2, "unexpected priority level"); test_assert(chThdGetPriorityX() == prio + 2, "unexpected priority level");
} }
test_end_step(1); test_end_step(1);
@ -305,7 +305,7 @@ static void rt_test_004_004_execute(void) {
{ {
p1 = chThdSetPriority(prio + 1); p1 = chThdSetPriority(prio + 1);
test_assert(p1 == prio, "unexpected returned priority level"); test_assert(p1 == prio, "unexpected returned priority level");
test_assert(chThdGetSelfX()->prio == prio + 2, "unexpected priority level"); test_assert(chThdGetSelfX()->hdr.pqueue.prio == prio + 2, "unexpected priority level");
test_assert(chThdGetSelfX()->realprio == prio + 1, "unexpected returned real priority level"); test_assert(chThdGetSelfX()->realprio == prio + 1, "unexpected returned real priority level");
} }
test_end_step(2); test_end_step(2);
@ -315,7 +315,7 @@ static void rt_test_004_004_execute(void) {
{ {
p1 = chThdSetPriority(prio + 3); p1 = chThdSetPriority(prio + 3);
test_assert(p1 == prio + 1, "unexpected returned priority level"); test_assert(p1 == prio + 1, "unexpected returned priority level");
test_assert(chThdGetSelfX()->prio == prio + 3, "unexpected priority level"); test_assert(chThdGetSelfX()->hdr.pqueue.prio == prio + 3, "unexpected priority level");
test_assert(chThdGetSelfX()->realprio == prio + 3, "unexpected real priority level"); test_assert(chThdGetSelfX()->realprio == prio + 3, "unexpected real priority level");
} }
test_end_step(3); test_end_step(3);
@ -324,7 +324,7 @@ static void rt_test_004_004_execute(void) {
test_set_step(4); test_set_step(4);
{ {
chSysLock(); chSysLock();
chThdGetSelfX()->prio = prio; chThdGetSelfX()->hdr.pqueue.prio = prio;
chThdGetSelfX()->realprio = prio; chThdGetSelfX()->realprio = prio;
chSysUnlock(); chSysUnlock();
} }

View File

@ -246,7 +246,7 @@ static void rt_test_006_003_execute(void) {
{ {
msg = chSemWaitTimeout(&sem1, TIME_IMMEDIATE); msg = chSemWaitTimeout(&sem1, TIME_IMMEDIATE);
test_assert(msg == MSG_TIMEOUT, "wrong wake-up message"); 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(sem1.cnt == 0, "counter not zero");
} }
test_end_step(1); test_end_step(1);
@ -259,7 +259,7 @@ static void rt_test_006_003_execute(void) {
msg = chSemWaitTimeout(&sem1, TIME_MS2I(500)); msg = chSemWaitTimeout(&sem1, TIME_MS2I(500));
test_wait_threads(); test_wait_threads();
test_assert(msg == MSG_OK, "wrong wake-up message"); 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_assert(sem1.cnt == 0, "counter not zero");
} }
test_end_step(2); test_end_step(2);
@ -272,7 +272,7 @@ static void rt_test_006_003_execute(void) {
test_emit_token('A' + i); test_emit_token('A' + i);
msg = chSemWaitTimeout(&sem1, TIME_MS2I(50)); msg = chSemWaitTimeout(&sem1, TIME_MS2I(50));
test_assert(msg == MSG_TIMEOUT, "wrong wake-up message"); 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(sem1.cnt == 0, "counter not zero");
} }
test_assert_sequence("ABCDE", "invalid sequence"); test_assert_sequence("ABCDE", "invalid sequence");
@ -386,7 +386,7 @@ static void rt_test_006_005_execute(void) {
test_set_step(2); test_set_step(2);
{ {
chSemSignalWait(&sem1, &sem1); 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_assert(sem1.cnt == 0, "counter not zero");
} }
test_end_step(2); test_end_step(2);
@ -397,7 +397,7 @@ static void rt_test_006_005_execute(void) {
test_set_step(3); test_set_step(3);
{ {
chSemSignalWait(&sem1, &sem1); 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_assert(sem1.cnt == 0, "counter not zero");
} }
test_end_step(3); test_end_step(3);

View File

@ -648,7 +648,7 @@ static void rt_test_007_005_execute(void) {
{ {
chMtxUnlock(&m1); chMtxUnlock(&m1);
test_assert(m1.owner == NULL, "still owned"); 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); test_end_step(4);
@ -669,7 +669,7 @@ static void rt_test_007_005_execute(void) {
chMtxUnlockAll(); chMtxUnlockAll();
test_assert(m1.owner == NULL, "still owned"); 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); test_end_step(6);
@ -770,7 +770,7 @@ static void rt_test_007_006_execute(void) {
{ {
chMtxUnlock(&m1); chMtxUnlock(&m1);
test_assert(m1.owner == NULL, "still owned"); 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(5); test_end_step(5);
@ -796,7 +796,7 @@ static void rt_test_007_006_execute(void) {
chMtxUnlockAllS(); chMtxUnlockAllS();
chSysUnlock(); chSysUnlock();
test_assert(m1.owner == NULL, "still owned"); 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_assert(m1.cnt == 0, "invalid recursion counter"); test_assert(m1.cnt == 0, "invalid recursion counter");
} }
test_end_step(7); test_end_step(7);
@ -814,7 +814,7 @@ static void rt_test_007_006_execute(void) {
test_assert(m1.cnt == 2, "invalid recursion counter"); test_assert(m1.cnt == 2, "invalid recursion counter");
chMtxUnlockAll(); chMtxUnlockAll();
test_assert(m1.owner == NULL, "still owned"); 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_assert(m1.cnt == 0, "invalid recursion counter"); test_assert(m1.cnt == 0, "invalid recursion counter");
} }
test_end_step(8); test_end_step(8);