Initial fix for bug #1138. To be completed by running all regression and quality checks.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13958 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
22a2569793
commit
817fe8f3de
|
@ -82,8 +82,8 @@ typedef struct {
|
||||||
(msg_t *)(buffer), \
|
(msg_t *)(buffer), \
|
||||||
(size_t)0, \
|
(size_t)0, \
|
||||||
false, \
|
false, \
|
||||||
_THREADS_QUEUE_DATA(name.qw), \
|
__THREADS_QUEUE_DATA(name.qw), \
|
||||||
_THREADS_QUEUE_DATA(name.qr), \
|
__THREADS_QUEUE_DATA(name.qr), \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -95,7 +95,7 @@ typedef struct {
|
||||||
* @param[in] align required memory alignment
|
* @param[in] align required memory alignment
|
||||||
* @param[in] provider memory provider function for the memory pool
|
* @param[in] provider memory provider function for the memory pool
|
||||||
*/
|
*/
|
||||||
#define _MEMORYPOOL_DATA(name, size, align, provider) \
|
#define __MEMORYPOOL_DATA(name, size, align, provider) \
|
||||||
{NULL, size, align, provider}
|
{NULL, size, align, provider}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,7 +110,7 @@ typedef struct {
|
||||||
* if the pool is not allowed to grow automatically
|
* if the pool is not allowed to grow automatically
|
||||||
*/
|
*/
|
||||||
#define MEMORYPOOL_DECL(name, size, align, provider) \
|
#define MEMORYPOOL_DECL(name, size, align, provider) \
|
||||||
memory_pool_t name = _MEMORYPOOL_DATA(name, size, align, provider)
|
memory_pool_t name = __MEMORYPOOL_DATA(name, size, align, provider)
|
||||||
|
|
||||||
#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
|
#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
|
||||||
/**
|
/**
|
||||||
|
@ -122,9 +122,9 @@ typedef struct {
|
||||||
* @param[in] size size of the memory pool contained objects
|
* @param[in] size size of the memory pool contained objects
|
||||||
* @param[in] align required memory alignment
|
* @param[in] align required memory alignment
|
||||||
*/
|
*/
|
||||||
#define _GUARDEDMEMORYPOOL_DATA(name, size, align) { \
|
#define __GUARDEDMEMORYPOOL_DATA(name, size, align) { \
|
||||||
_SEMAPHORE_DATA(name.sem, (cnt_t)0), \
|
__SEMAPHORE_DATA(name.sem, (cnt_t)0), \
|
||||||
_MEMORYPOOL_DATA(NULL, size, align, NULL) \
|
__MEMORYPOOL_DATA(NULL, size, align, NULL) \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -137,7 +137,7 @@ typedef struct {
|
||||||
* @param[in] align required memory alignment
|
* @param[in] align required memory alignment
|
||||||
*/
|
*/
|
||||||
#define GUARDEDMEMORYPOOL_DECL(name, size, align) \
|
#define GUARDEDMEMORYPOOL_DECL(name, size, align) \
|
||||||
guarded_memory_pool_t name = _GUARDEDMEMORYPOOL_DATA(name, size, align)
|
guarded_memory_pool_t name = __GUARDEDMEMORYPOOL_DATA(name, size, align)
|
||||||
#endif /* CH_CFG_USE_SEMAPHORES == TRUE */
|
#endif /* CH_CFG_USE_SEMAPHORES == TRUE */
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
|
@ -85,7 +85,7 @@ typedef struct {
|
||||||
* @param[in] size number of @p uint8_t elements in the buffer array
|
* @param[in] size number of @p uint8_t elements in the buffer array
|
||||||
*/
|
*/
|
||||||
#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
|
#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
|
||||||
#define _PIPE_DATA(name, buffer, size) { \
|
#define __PIPE_DATA(name, buffer, size) { \
|
||||||
(uint8_t *)(buffer), \
|
(uint8_t *)(buffer), \
|
||||||
(uint8_t *)(buffer) + size, \
|
(uint8_t *)(buffer) + size, \
|
||||||
(uint8_t *)(buffer), \
|
(uint8_t *)(buffer), \
|
||||||
|
@ -94,9 +94,9 @@ typedef struct {
|
||||||
false, \
|
false, \
|
||||||
NULL, \
|
NULL, \
|
||||||
NULL, \
|
NULL, \
|
||||||
_MUTEX_DATA(name.cmtx), \
|
__MUTEX_DATA(name.cmtx), \
|
||||||
_MUTEX_DATA(name.wmtx), \
|
__MUTEX_DATA(name.wmtx), \
|
||||||
_MUTEX_DATA(name.rmtx), \
|
__MUTEX_DATA(name.rmtx), \
|
||||||
}
|
}
|
||||||
#else /* CH_CFG_USE_MUTEXES == FALSE */
|
#else /* CH_CFG_USE_MUTEXES == FALSE */
|
||||||
#define _PIPE_DATA(name, buffer, size) { \
|
#define _PIPE_DATA(name, buffer, size) { \
|
||||||
|
@ -108,9 +108,9 @@ typedef struct {
|
||||||
false, \
|
false, \
|
||||||
NULL, \
|
NULL, \
|
||||||
NULL, \
|
NULL, \
|
||||||
_SEMAPHORE_DATA(name.csem, (cnt_t)1), \
|
__SEMAPHORE_DATA(name.csem, (cnt_t)1), \
|
||||||
_SEMAPHORE_DATA(name.wsem, (cnt_t)1), \
|
__SEMAPHORE_DATA(name.wsem, (cnt_t)1), \
|
||||||
_SEMAPHORE_DATA(name.rsem, (cnt_t)1), \
|
__SEMAPHORE_DATA(name.rsem, (cnt_t)1), \
|
||||||
}
|
}
|
||||||
#endif /* CH_CFG_USE_MUTEXES == FALSE */
|
#endif /* CH_CFG_USE_MUTEXES == FALSE */
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ typedef struct {
|
||||||
* @param[in] size number of @p uint8_t elements in the buffer array
|
* @param[in] size number of @p uint8_t elements in the buffer array
|
||||||
*/
|
*/
|
||||||
#define PIPE_DECL(name, buffer, size) \
|
#define PIPE_DECL(name, buffer, size) \
|
||||||
pipe_t name = _PIPE_DATA(name, buffer, size)
|
pipe_t name = __PIPE_DATA(name, buffer, size)
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* External declarations. */
|
/* External declarations. */
|
||||||
|
|
|
@ -97,6 +97,7 @@
|
||||||
/* Base kernel headers.*/
|
/* Base kernel headers.*/
|
||||||
#include "chtypes.h"
|
#include "chtypes.h"
|
||||||
#include "chearly.h"
|
#include "chearly.h"
|
||||||
|
#include "chlists.h"
|
||||||
#include "chalign.h"
|
#include "chalign.h"
|
||||||
#include "chdebug.h"
|
#include "chdebug.h"
|
||||||
#include "chtime.h"
|
#include "chtime.h"
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -81,7 +81,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_DECL(name) condition_variable_t name = _CONDVAR_DATA(name)
|
#define CONDVAR_DECL(name) condition_variable_t name = __CONDVAR_DATA(name)
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* External declarations. */
|
/* External declarations. */
|
||||||
|
|
|
@ -72,16 +72,12 @@ struct ch_queue {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @extends ch_queue_t
|
|
||||||
*
|
|
||||||
* @brief Type of a generic priority-ordered bidirectional linked list
|
* @brief Type of a generic priority-ordered bidirectional linked list
|
||||||
* header and element.
|
* header and element.
|
||||||
*/
|
*/
|
||||||
typedef struct ch_priority_queue ch_priority_queue_t;
|
typedef struct ch_priority_queue ch_priority_queue_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @extends ch_queue_t
|
|
||||||
*
|
|
||||||
* @brief Structure representing a generic priority-ordered bidirectional
|
* @brief Structure representing a generic priority-ordered bidirectional
|
||||||
* linked list header and element.
|
* linked list header and element.
|
||||||
* @note Link fields are void pointers in order to avoid aliasing issues.
|
* @note Link fields are void pointers in order to avoid aliasing issues.
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,7 +90,7 @@ struct ch_mutex {
|
||||||
*
|
*
|
||||||
* @param[in] name the name of the mutex variable
|
* @param[in] name the name of the mutex variable
|
||||||
*/
|
*/
|
||||||
#define MUTEX_DECL(name) mutex_t name = _MUTEX_DATA(name)
|
#define MUTEX_DECL(name) mutex_t name = __MUTEX_DATA(name)
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* External declarations. */
|
/* External declarations. */
|
||||||
|
@ -129,7 +129,7 @@ static inline bool chMtxQueueNotEmptyS(mutex_t *mp) {
|
||||||
|
|
||||||
chDbgCheckClassS();
|
chDbgCheckClassS();
|
||||||
|
|
||||||
return queue_notempty(&mp->queue);
|
return ch_queue_notempty(&mp->queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -50,24 +50,29 @@
|
||||||
typedef void (*vtfunc_t)(void *p);
|
typedef void (*vtfunc_t)(void *p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @extends virtual_timers_list_t
|
|
||||||
*
|
|
||||||
* @brief Type of a Virtual Timer structure.
|
* @brief Type of a Virtual Timer structure.
|
||||||
*/
|
*/
|
||||||
typedef struct ch_virtual_timer virtual_timer_t;
|
typedef struct ch_delta_list delta_list_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Virtual Timer descriptor structure.
|
* @brief Virtual Timer delta list element and header structure.
|
||||||
*/
|
*/
|
||||||
struct ch_virtual_timer {
|
struct ch_delta_list {
|
||||||
virtual_timer_t *next; /**< @brief Next timer in the list. */
|
delta_list_t *next; /**< @brief Next timer in the list. */
|
||||||
virtual_timer_t *prev; /**< @brief Previous 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 Type of virtual timers list header.
|
* @brief Type of virtual timers list header.
|
||||||
|
@ -76,11 +81,7 @@ struct ch_virtual_timer {
|
||||||
* timer is often used in the code.
|
* timer is often used in the code.
|
||||||
*/
|
*/
|
||||||
typedef 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
|
||||||
|
@ -102,21 +103,10 @@ typedef struct ch_virtual_timers_list {
|
||||||
typedef thread_t * thread_reference_t;
|
typedef thread_t * thread_reference_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type of a generic threads single link list, it works like a stack.
|
* @brief Type of a threads queue.
|
||||||
*/
|
|
||||||
typedef struct ch_threads_list {
|
|
||||||
thread_t *next; /**< @brief Next in the list/queue. */
|
|
||||||
} threads_list_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @extends threads_list_t
|
|
||||||
*
|
|
||||||
* @brief Type of a generic threads bidirectional linked list header and
|
|
||||||
* element.
|
|
||||||
*/
|
*/
|
||||||
typedef struct ch_threads_queue {
|
typedef struct ch_threads_queue {
|
||||||
thread_t *next; /**< @brief Next in the list/queue. */
|
ch_queue_t queue; /**< @brief Threads queue header. */
|
||||||
thread_t *prev; /**< @brief Previous in the queue. */
|
|
||||||
} threads_queue_t;
|
} threads_queue_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,7 +116,10 @@ typedef 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 {
|
||||||
|
ch_list_t list; /**< @brief Threads list header. */
|
||||||
|
ch_queue_t queue; /**< @brief Threads queue header. */
|
||||||
|
} hdr;
|
||||||
tprio_t prio; /**< @brief Thread priority. */
|
tprio_t prio; /**< @brief Thread priority. */
|
||||||
#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. */
|
||||||
|
@ -250,13 +243,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__)
|
||||||
/**
|
/**
|
||||||
|
@ -300,7 +293,7 @@ struct ch_thread {
|
||||||
* @brief Type of a ready list header.
|
* @brief Type of a ready list header.
|
||||||
*/
|
*/
|
||||||
typedef struct ch_ready_list {
|
typedef struct ch_ready_list {
|
||||||
threads_queue_t queue; /**< @brief Threads queue. */
|
ch_queue_t queue; /**< @brief Threads queue. */
|
||||||
tprio_t prio; /**< @brief This field must be
|
tprio_t prio; /**< @brief This field must be
|
||||||
initialized to zero. */
|
initialized to zero. */
|
||||||
#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
|
#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
|
||||||
|
|
|
@ -127,7 +127,7 @@
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
#define firstprio(rlp) ((rlp)->next->prio)
|
#define firstprio(rlp) (((thread_t *)(rlp)->next)->prio)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Current thread pointer get macro.
|
* @brief Current thread pointer get macro.
|
||||||
|
@ -180,144 +180,19 @@ 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 queue_prio_insert(thread_t *tp, ch_queue_t *tqp) {
|
||||||
|
|
||||||
tp->queue.next = tlp->next;
|
|
||||||
tlp->next = tp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline thread_t *list_remove(threads_list_t *tlp) {
|
|
||||||
|
|
||||||
thread_t *tp = tlp->next;
|
|
||||||
tlp->next = tp->queue.next;
|
|
||||||
|
|
||||||
return tp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void queue_prio_insert(thread_t *tp, threads_queue_t *tqp) {
|
|
||||||
|
|
||||||
thread_t *cp = (thread_t *)tqp;
|
thread_t *cp = (thread_t *)tqp;
|
||||||
do {
|
do {
|
||||||
cp = cp->queue.next;
|
cp = (thread_t *)cp->hdr.queue.next;
|
||||||
} while ((cp != (thread_t *)tqp) && (cp->prio >= tp->prio));
|
} while ((cp != (thread_t *)tqp) && (cp->prio >= tp->prio));
|
||||||
tp->queue.next = cp;
|
tp->hdr.queue.next = (ch_queue_t *)cp;
|
||||||
tp->queue.prev = cp->queue.prev;
|
tp->hdr.queue.prev = cp->hdr.queue.prev;
|
||||||
tp->queue.prev->queue.next = tp;
|
tp->hdr.queue.prev->next = (ch_queue_t *)tp;
|
||||||
cp->queue.prev = tp;
|
cp->hdr.queue.prev = (ch_queue_t *)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 */
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -79,7 +79,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_DECL(name, n) semaphore_t name = _SEMAPHORE_DATA(name, n)
|
#define SEMAPHORE_DECL(name, n) semaphore_t name = __SEMAPHORE_DATA(name, n)
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* External declarations. */
|
/* External declarations. */
|
||||||
|
|
|
@ -384,8 +384,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((currcore->rlist.queue.next == (thread_t *)&currcore->rlist.queue) ||
|
chDbgAssert((currcore->rlist.queue.next == &currcore->rlist.queue) ||
|
||||||
(currcore->rlist.current->prio >= currcore->rlist.queue.next->prio),
|
(currcore->rlist.current->prio >= ((thread_t *)currcore->rlist.queue.next)->prio),
|
||||||
"priority order violation");
|
"priority order violation");
|
||||||
|
|
||||||
port_unlock();
|
port_unlock();
|
||||||
|
@ -477,7 +477,7 @@ static inline void chSysUnconditionalUnlock(void) {
|
||||||
*/
|
*/
|
||||||
static inline thread_t *chSysGetIdleThreadX(void) {
|
static inline thread_t *chSysGetIdleThreadX(void) {
|
||||||
|
|
||||||
return currcore->rlist.queue.prev;
|
return (thread_t *)currcore->rlist.queue.prev;
|
||||||
}
|
}
|
||||||
#endif /* CH_CFG_NO_IDLE_THREAD == FALSE */
|
#endif /* CH_CFG_NO_IDLE_THREAD == FALSE */
|
||||||
|
|
||||||
|
|
|
@ -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,8 +104,8 @@ 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)
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -394,7 +394,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -411,7 +411,7 @@ static inline bool chThdQueueIsEmptyI(threads_queue_t *tqp) {
|
||||||
|
|
||||||
chDbgCheckClassI();
|
chDbgCheckClassI();
|
||||||
|
|
||||||
return queue_isempty(tqp);
|
return ch_queue_isempty(&tqp->queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -428,9 +428,9 @@ static inline bool chThdQueueIsEmptyI(threads_queue_t *tqp) {
|
||||||
static inline void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg) {
|
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");
|
||||||
|
|
||||||
|
|
|
@ -212,10 +212,11 @@ static inline bool chVTIsSystemTimeWithin(systime_t start, systime_t end) {
|
||||||
*/
|
*/
|
||||||
static inline bool chVTGetTimersStateI(sysinterval_t *timep) {
|
static inline bool chVTGetTimersStateI(sysinterval_t *timep) {
|
||||||
virtual_timers_list_t *vtlp = &currcore->vtlist;
|
virtual_timers_list_t *vtlp = &currcore->vtlist;
|
||||||
|
delta_list_t *dlp = &vtlp->dlist;
|
||||||
|
|
||||||
chDbgCheckClassI();
|
chDbgCheckClassI();
|
||||||
|
|
||||||
if (vtlp == (virtual_timers_list_t *)vtlp->next) {
|
if (dlp == dlp->next) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +224,7 @@ static inline bool chVTGetTimersStateI(sysinterval_t *timep) {
|
||||||
#if CH_CFG_ST_TIMEDELTA == 0
|
#if CH_CFG_ST_TIMEDELTA == 0
|
||||||
*timep = vtlp->next->delta;
|
*timep = vtlp->next->delta;
|
||||||
#else
|
#else
|
||||||
*timep = (vtlp->next->delta + (sysinterval_t)CH_CFG_ST_TIMEDELTA) -
|
*timep = (dlp->next->delta + (sysinterval_t)CH_CFG_ST_TIMEDELTA) -
|
||||||
chTimeDiffX(vtlp->lasttime, chVTGetSystemTimeX());
|
chTimeDiffX(vtlp->lasttime, chVTGetSystemTimeX());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -416,9 +417,9 @@ static inline void chVTResetTimeStamp(void) {
|
||||||
*/
|
*/
|
||||||
static inline void __vt_object_init(virtual_timers_list_t *vtlp) {
|
static inline void __vt_object_init(virtual_timers_list_t *vtlp) {
|
||||||
|
|
||||||
vtlp->next = (virtual_timer_t *)vtlp;
|
vtlp->dlist.next = &vtlp->dlist;
|
||||||
vtlp->prev = (virtual_timer_t *)vtlp;
|
vtlp->dlist.prev = &vtlp->dlist;
|
||||||
vtlp->delta = (sysinterval_t)-1;
|
vtlp->dlist.delta = (sysinterval_t)-1;
|
||||||
#if CH_CFG_ST_TIMEDELTA == 0
|
#if CH_CFG_ST_TIMEDELTA == 0
|
||||||
vtlp->systime = (systime_t)0;
|
vtlp->systime = (systime_t)0;
|
||||||
#else /* CH_CFG_ST_TIMEDELTA > 0 */
|
#else /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
#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) queue_prio_insert(tp, qp)
|
||||||
#else
|
#else
|
||||||
#define msg_insert(tp, qp) queue_insert(tp, qp)
|
#define msg_insert(tp, qp) ch_queue_insert((ch_queue_t *)tp, qp)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -127,7 +127,7 @@ thread_t *chMsgWaitS(void) {
|
||||||
if (!chMsgIsPendingI(currtp)) {
|
if (!chMsgIsPendingI(currtp)) {
|
||||||
chSchGoSleepS(CH_STATE_WTMSG);
|
chSchGoSleepS(CH_STATE_WTMSG);
|
||||||
}
|
}
|
||||||
tp = queue_fifo_remove(&currtp->msgqueue);
|
tp = (thread_t *)ch_queue_fifo_remove(&currtp->msgqueue);
|
||||||
tp->state = CH_STATE_SNDMSG;
|
tp->state = CH_STATE_SNDMSG;
|
||||||
|
|
||||||
return tp;
|
return tp;
|
||||||
|
@ -166,7 +166,7 @@ thread_t *chMsgWaitTimeoutS(sysinterval_t timeout) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tp = queue_fifo_remove(&currtp->msgqueue);
|
tp = (thread_t *)ch_queue_fifo_remove(&currtp->msgqueue);
|
||||||
tp->state = CH_STATE_SNDMSG;
|
tp->state = CH_STATE_SNDMSG;
|
||||||
|
|
||||||
return tp;
|
return tp;
|
||||||
|
@ -194,7 +194,7 @@ thread_t *chMsgPollS(void) {
|
||||||
thread_t *tp = NULL;
|
thread_t *tp = NULL;
|
||||||
|
|
||||||
if (chMsgIsPendingI(currtp)) {
|
if (chMsgIsPendingI(currtp)) {
|
||||||
tp = queue_fifo_remove(&currtp->msgqueue);
|
tp = (thread_t *)ch_queue_fifo_remove(&currtp->msgqueue);
|
||||||
tp->state = CH_STATE_SNDMSG;
|
tp->state = CH_STATE_SNDMSG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -170,7 +170,8 @@ void chMtxLockS(mutex_t *mp) {
|
||||||
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);
|
queue_prio_insert((thread_t *)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);
|
queue_prio_insert((thread_t *)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.*/
|
||||||
|
@ -357,8 +359,8 @@ void chMtxUnlock(mutex_t *mp) {
|
||||||
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)->prio > newprio)) {
|
||||||
newprio = lmp->queue.next->prio;
|
newprio = ((thread_t *)lmp->queue.next)->prio;
|
||||||
}
|
}
|
||||||
lmp = lmp->next;
|
lmp = lmp->next;
|
||||||
}
|
}
|
||||||
|
@ -372,7 +374,7 @@ void chMtxUnlock(mutex_t *mp) {
|
||||||
#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;
|
||||||
|
@ -443,8 +445,8 @@ void chMtxUnlockS(mutex_t *mp) {
|
||||||
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)->prio > newprio)) {
|
||||||
newprio = lmp->queue.next->prio;
|
newprio = ((thread_t *)lmp->queue.next)->prio;
|
||||||
}
|
}
|
||||||
lmp = lmp->next;
|
lmp = lmp->next;
|
||||||
}
|
}
|
||||||
|
@ -458,7 +460,7 @@ void chMtxUnlockS(mutex_t *mp) {
|
||||||
#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;
|
||||||
|
@ -497,7 +499,7 @@ void chMtxUnlockAllS(void) {
|
||||||
#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;
|
||||||
|
|
|
@ -91,7 +91,7 @@ static void __idle_thread(void *p) {
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
static thread_t *__sch_ready_behind(os_instance_t *oip, thread_t *tp) {
|
static thread_t *__sch_ready_behind(os_instance_t *oip, thread_t *tp) {
|
||||||
thread_t *cp;
|
ch_queue_t *cqp, *tqp;
|
||||||
|
|
||||||
chDbgAssert((tp->state != CH_STATE_READY) &&
|
chDbgAssert((tp->state != CH_STATE_READY) &&
|
||||||
(tp->state != CH_STATE_FINAL),
|
(tp->state != CH_STATE_FINAL),
|
||||||
|
@ -102,16 +102,17 @@ static thread_t *__sch_ready_behind(os_instance_t *oip, thread_t *tp) {
|
||||||
|
|
||||||
/* Scanning ready list.*/
|
/* Scanning ready list.*/
|
||||||
tp->state = CH_STATE_READY;
|
tp->state = CH_STATE_READY;
|
||||||
cp = (thread_t *)&oip->rlist.queue;
|
tqp = &tp->hdr.queue;
|
||||||
|
cqp = &oip->rlist.queue;
|
||||||
do {
|
do {
|
||||||
cp = cp->queue.next;
|
cqp = cqp->next;
|
||||||
} while (cp->prio >= tp->prio);
|
} while (((thread_t *)cqp)->prio >= tp->prio);
|
||||||
|
|
||||||
/* Insertion on prev.*/
|
/* Insertion on prev.*/
|
||||||
tp->queue.next = cp;
|
tqp->next = cqp;
|
||||||
tp->queue.prev = cp->queue.prev;
|
tqp->prev = cqp->prev;
|
||||||
tp->queue.prev->queue.next = tp;
|
tqp->prev->next = &tp->hdr.queue;
|
||||||
cp->queue.prev = tp;
|
cqp->prev = tqp;
|
||||||
|
|
||||||
return tp;
|
return tp;
|
||||||
}
|
}
|
||||||
|
@ -134,7 +135,7 @@ static thread_t *__sch_ready_behind(os_instance_t *oip, thread_t *tp) {
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
static thread_t *__sch_ready_ahead(os_instance_t *oip, thread_t *tp) {
|
static thread_t *__sch_ready_ahead(os_instance_t *oip, thread_t *tp) {
|
||||||
thread_t *cp;
|
ch_queue_t *cqp, *tqp;
|
||||||
|
|
||||||
chDbgAssert((tp->state != CH_STATE_READY) &&
|
chDbgAssert((tp->state != CH_STATE_READY) &&
|
||||||
(tp->state != CH_STATE_FINAL),
|
(tp->state != CH_STATE_FINAL),
|
||||||
|
@ -145,16 +146,17 @@ static thread_t *__sch_ready_ahead(os_instance_t *oip, thread_t *tp) {
|
||||||
|
|
||||||
/* Scanning ready list.*/
|
/* Scanning ready list.*/
|
||||||
tp->state = CH_STATE_READY;
|
tp->state = CH_STATE_READY;
|
||||||
cp = (thread_t *)&oip->rlist.queue;
|
tqp = &tp->hdr.queue;
|
||||||
|
cqp = &oip->rlist.queue;
|
||||||
do {
|
do {
|
||||||
cp = cp->queue.next;
|
cqp = cqp->next;
|
||||||
} while (cp->prio > tp->prio);
|
} while (((thread_t *)cqp)->prio > tp->prio);
|
||||||
|
|
||||||
/* Insertion on prev.*/
|
/* Insertion on prev.*/
|
||||||
tp->queue.next = cp;
|
tqp->next = cqp;
|
||||||
tp->queue.prev = cp->queue.prev;
|
tqp->prev = cqp->prev;
|
||||||
tp->queue.prev->queue.next = tp;
|
tqp->prev->next = tqp;
|
||||||
cp->queue.prev = tp;
|
cqp->prev = tqp;
|
||||||
|
|
||||||
return tp;
|
return tp;
|
||||||
}
|
}
|
||||||
|
@ -176,7 +178,7 @@ static void __sch_reschedule_behind(os_instance_t *oip) {
|
||||||
thread_t *ntp;
|
thread_t *ntp;
|
||||||
|
|
||||||
/* Picks the first thread from the ready queue and makes it current.*/
|
/* Picks the first thread from the ready queue and makes it current.*/
|
||||||
ntp = queue_fifo_remove(&oip->rlist.queue);
|
ntp = (thread_t *)ch_queue_fifo_remove(&oip->rlist.queue);
|
||||||
ntp->state = CH_STATE_CURRENT;
|
ntp->state = CH_STATE_CURRENT;
|
||||||
__sch_set_currthread(oip, ntp);
|
__sch_set_currthread(oip, ntp);
|
||||||
|
|
||||||
|
@ -213,7 +215,7 @@ static void __sch_reschedule_ahead(os_instance_t *oip) {
|
||||||
thread_t *ntp;
|
thread_t *ntp;
|
||||||
|
|
||||||
/* Picks the first thread from the ready queue and makes it current.*/
|
/* Picks the first thread from the ready queue and makes it current.*/
|
||||||
ntp = queue_fifo_remove(&oip->rlist.queue);
|
ntp = (thread_t *)ch_queue_fifo_remove(&oip->rlist.queue);
|
||||||
ntp->state = CH_STATE_CURRENT;
|
ntp->state = CH_STATE_CURRENT;
|
||||||
__sch_set_currthread(oip, ntp);
|
__sch_set_currthread(oip, ntp);
|
||||||
|
|
||||||
|
@ -256,7 +258,7 @@ static void __sch_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.*/
|
||||||
|
@ -297,109 +299,6 @@ void queue_prio_insert(thread_t *tp, threads_queue_t *tqp) {
|
||||||
tp->queue.prev->queue.next = tp;
|
tp->queue.prev->queue.next = tp;
|
||||||
cp->queue.prev = 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 */
|
#endif /* CH_CFG_OPTIMIZE_SPEED */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -418,7 +317,7 @@ void chSchObjectInit(os_instance_t *oip,
|
||||||
port_init(oip);
|
port_init(oip);
|
||||||
|
|
||||||
/* Ready list initialization.*/
|
/* Ready list initialization.*/
|
||||||
queue_init(&oip->rlist.queue);
|
ch_queue_init(&oip->rlist.queue);
|
||||||
oip->rlist.prio = NOPRIO;
|
oip->rlist.prio = NOPRIO;
|
||||||
|
|
||||||
/* Registry initialization.*/
|
/* Registry initialization.*/
|
||||||
|
@ -544,7 +443,7 @@ void chSchGoSleepS(tstate_t newstate) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Next thread in ready list becomes current.*/
|
/* Next thread in ready list becomes current.*/
|
||||||
ntp = queue_fifo_remove(&oip->rlist.queue);
|
ntp = (thread_t *)ch_queue_fifo_remove(&oip->rlist.queue);
|
||||||
ntp->state = CH_STATE_CURRENT;
|
ntp->state = CH_STATE_CURRENT;
|
||||||
__sch_set_currthread(oip, ntp);
|
__sch_set_currthread(oip, ntp);
|
||||||
|
|
||||||
|
@ -622,8 +521,8 @@ void chSchWakeupS(thread_t *ntp, msg_t msg) {
|
||||||
|
|
||||||
chDbgCheckClassS();
|
chDbgCheckClassS();
|
||||||
|
|
||||||
chDbgAssert((oip->rlist.queue.next == (thread_t *)&oip->rlist.queue) ||
|
chDbgAssert((oip->rlist.queue.next == &oip->rlist.queue) ||
|
||||||
(oip->rlist.current->prio >= oip->rlist.queue.next->prio),
|
(oip->rlist.current->prio >= ((thread_t *)oip->rlist.queue.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
|
||||||
|
@ -728,7 +627,7 @@ void chSchDoPreemption(void) {
|
||||||
thread_t *ntp;
|
thread_t *ntp;
|
||||||
|
|
||||||
/* Picks the first thread from the ready queue and makes it current.*/
|
/* Picks the first thread from the ready queue and makes it current.*/
|
||||||
ntp = queue_fifo_remove(&oip->rlist.queue);
|
ntp = (thread_t *)ch_queue_fifo_remove(&oip->rlist.queue);
|
||||||
ntp->state = CH_STATE_CURRENT;
|
ntp->state = CH_STATE_CURRENT;
|
||||||
__sch_set_currthread(oip, ntp);
|
__sch_set_currthread(oip, ntp);
|
||||||
|
|
||||||
|
@ -834,7 +733,7 @@ thread_t *chSchSelectFirstI(void) {
|
||||||
thread_t *ntp;
|
thread_t *ntp;
|
||||||
|
|
||||||
/* Picks the first thread from the ready queue and makes it current.*/
|
/* Picks the first thread from the ready queue and makes it current.*/
|
||||||
ntp = queue_fifo_remove(&oip->rlist.queue);
|
ntp = (thread_t *)ch_queue_fifo_remove(&oip->rlist.queue);
|
||||||
ntp->state = CH_STATE_CURRENT;
|
ntp->state = CH_STATE_CURRENT;
|
||||||
__sch_set_currthread(oip, ntp);
|
__sch_set_currthread(oip, ntp);
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@
|
||||||
#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) queue_prio_insert(tp, qp)
|
||||||
#else
|
#else
|
||||||
#define sem_insert(tp, qp) queue_insert(tp, qp)
|
#define sem_insert(tp, qp) ch_queue_insert((ch_queue_t *)tp, 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) {
|
||||||
|
@ -260,8 +260,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) {
|
||||||
|
@ -292,11 +292,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();
|
||||||
}
|
}
|
||||||
|
@ -316,14 +316,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);
|
||||||
}
|
}
|
||||||
|
@ -346,13 +346,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--;
|
||||||
}
|
}
|
||||||
|
@ -377,14 +377,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 *currtp = chThdGetSelfX();
|
thread_t *currtp = chThdGetSelfX();
|
||||||
|
|
|
@ -172,21 +172,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_queue_t *qp;
|
||||||
|
|
||||||
/* Scanning the ready list forward.*/
|
/* Scanning the ready list forward.*/
|
||||||
n = (cnt_t)0;
|
n = (cnt_t)0;
|
||||||
tp = oip->rlist.queue.next;
|
qp = oip->rlist.queue.next;
|
||||||
while (tp != (thread_t *)&oip->rlist.queue) {
|
while (qp != &oip->rlist.queue) {
|
||||||
n++;
|
n++;
|
||||||
tp = tp->queue.next;
|
qp = qp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scanning the ready list backward.*/
|
/* Scanning the ready list backward.*/
|
||||||
tp = oip->rlist.queue.prev;
|
qp = oip->rlist.queue.prev;
|
||||||
while (tp != (thread_t *)&oip->rlist.queue) {
|
while (qp != &oip->rlist.queue) {
|
||||||
n--;
|
n--;
|
||||||
tp = tp->queue.prev;
|
qp = qp->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The number of elements must match.*/
|
/* The number of elements must match.*/
|
||||||
|
@ -197,21 +197,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 = oip->vtlist.next;
|
dlp = oip->vtlist.dlist.next;
|
||||||
while (vtp != (virtual_timer_t *)&oip->vtlist) {
|
while (dlp != &oip->vtlist.dlist) {
|
||||||
n++;
|
n++;
|
||||||
vtp = vtp->next;
|
dlp = dlp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scanning the timers list backward.*/
|
/* Scanning the timers list backward.*/
|
||||||
vtp = oip->vtlist.prev;
|
dlp = oip->vtlist.dlist.prev;
|
||||||
while (vtp != (virtual_timer_t *)&oip->vtlist) {
|
while (dlp != &oip->vtlist.dlist) {
|
||||||
n--;
|
n--;
|
||||||
vtp = vtp->prev;
|
dlp = dlp->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The number of elements must match.*/
|
/* The number of elements must match.*/
|
||||||
|
|
|
@ -118,10 +118,10 @@ thread_t *__thd_object_init(os_instance_t *oip,
|
||||||
(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);
|
||||||
|
@ -515,8 +515,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(&currtp->waiting)) {
|
while (ch_list_notempty(&currtp->waiting)) {
|
||||||
(void) chSchReadyI(list_remove(&currtp->waiting));
|
(void) chSchReadyI((thread_t *)ch_list_pop(&currtp->waiting));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -575,7 +575,7 @@ msg_t chThdWait(thread_t *tp) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (tp->state != CH_STATE_FINAL) {
|
if (tp->state != CH_STATE_FINAL) {
|
||||||
list_insert(currtp, &tp->waiting);
|
ch_list_push(&currtp->hdr.list, &tp->waiting);
|
||||||
chSchGoSleepS(CH_STATE_WTEXIT);
|
chSchGoSleepS(CH_STATE_WTEXIT);
|
||||||
}
|
}
|
||||||
msg = tp->u.exitcode;
|
msg = tp->u.exitcode;
|
||||||
|
@ -876,7 +876,7 @@ msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout) {
|
||||||
return MSG_TIMEOUT;
|
return MSG_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
queue_insert(currtp, tqp);
|
ch_queue_insert((ch_queue_t *)currtp, &tqp->queue);
|
||||||
|
|
||||||
return chSchGoSleepTimeoutS(CH_STATE_QUEUED, timeout);
|
return chSchGoSleepTimeoutS(CH_STATE_QUEUED, timeout);
|
||||||
}
|
}
|
||||||
|
@ -892,7 +892,7 @@ msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout) {
|
||||||
*/
|
*/
|
||||||
void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -907,7 +907,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
203
os/rt/src/chvt.c
203
os/rt/src/chvt.c
|
@ -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,6 +48,57 @@
|
||||||
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Last timer in the list check.
|
||||||
|
*
|
||||||
|
* @param[in] dlhp pointer to the delta list header
|
||||||
|
* @param[in] dlp pointer to the delta list element
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static inline bool is_last_timer(delta_list_t *dlhp, delta_list_t *dlp) {
|
||||||
|
|
||||||
|
return (bool)(dlp->next == dlhp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fist timer in the list check.
|
||||||
|
*
|
||||||
|
* @param[in] dlhp pointer to the delta list header
|
||||||
|
* @param[in] dlp pointer to the delta list element
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static inline bool is_first_timer(delta_list_t *dlhp, delta_list_t *dlp) {
|
||||||
|
|
||||||
|
return (bool)(dlhp->next == dlp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Timer check.
|
||||||
|
*
|
||||||
|
* @param[in] dlhp pointer to the delta list header
|
||||||
|
* @param[in] dlp pointer to the delta list element
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static inline bool is_timer(delta_list_t *dlhp, delta_list_t *dlp) {
|
||||||
|
|
||||||
|
return (bool)(dlp != dlhp);
|
||||||
|
}
|
||||||
|
|
||||||
#if (CH_CFG_ST_TIMEDELTA > 0) || defined(__DOXYGEN__)
|
#if (CH_CFG_ST_TIMEDELTA > 0) || defined(__DOXYGEN__)
|
||||||
/**
|
/**
|
||||||
* @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
|
||||||
|
@ -146,7 +158,7 @@ static void vt_list_compress(virtual_timers_list_t *vtlp,
|
||||||
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 = &currcore->vtlist;
|
virtual_timers_list_t *vtlp = &currcore->vtlist;
|
||||||
virtual_timer_t *p;
|
delta_list_t *dlp;
|
||||||
sysinterval_t delta;
|
sysinterval_t delta;
|
||||||
|
|
||||||
chDbgCheckClassI();
|
chDbgCheckClassI();
|
||||||
|
@ -167,16 +179,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.*/
|
||||||
|
@ -202,7 +214,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
|
||||||
|
@ -224,28 +236,28 @@ void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay,
|
||||||
|
|
||||||
/* The delta list is scanned in order to find the correct position for
|
/* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -281,37 +293,37 @@ void chVTDoResetI(virtual_timer_t *vtp) {
|
||||||
|
|
||||||
/* If the timer is not the first of the list then it is simply unlinked
|
/* 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;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
@ -320,12 +332,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,12 +391,12 @@ void chVTDoTickI(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#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.*/
|
||||||
|
@ -392,29 +404,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;
|
||||||
|
|
||||||
/* Marking the timer as non active.*/
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,23 +439,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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,7 +246,7 @@ static void rt_test_007_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_007_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_007_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_007_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_007_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);
|
||||||
|
|
|
@ -648,7 +648,7 @@ static void rt_test_008_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_008_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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue