git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6167 35acf78f-673a-0410-8e92-d51de3d6d3f4
parent
bfa3ba9f00
commit
4f49b546b1
|
@ -84,153 +84,4 @@ void osalSysHalt(const char *reason) {
|
||||||
chSysHalt();
|
chSysHalt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Sends the current thread sleeping and sets a reference variable.
|
|
||||||
* @note This function must reschedule, it can only be called from thread
|
|
||||||
* context.
|
|
||||||
*
|
|
||||||
* @param[in] trp a pointer to a thread reference object
|
|
||||||
* @return The wake up message.
|
|
||||||
*
|
|
||||||
* @sclass
|
|
||||||
*/
|
|
||||||
msg_t osalThreadSuspendS(thread_reference_t *trp) {
|
|
||||||
|
|
||||||
chDbgAssert(*trp == NULL, "not NULL");
|
|
||||||
|
|
||||||
*trp = (thread_reference_t)chThdGetSelfX();
|
|
||||||
chSchGoSleepS(CH_STATE_SUSPENDED);
|
|
||||||
return chThdGetSelfX()->p_msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Wakes up a thread waiting on a thread reference object.
|
|
||||||
* @note This function must not reschedule because it can be called from
|
|
||||||
* ISR context.
|
|
||||||
*
|
|
||||||
* @param[in] trp a pointer to a thread reference object
|
|
||||||
* @param[in] msg the message code
|
|
||||||
*
|
|
||||||
* @iclass
|
|
||||||
*/
|
|
||||||
void osalThreadResumeI(thread_reference_t *trp, msg_t msg) {
|
|
||||||
|
|
||||||
if (*trp != NULL) {
|
|
||||||
|
|
||||||
chDbgAssert((*trp)->p_state == CH_STATE_SUSPENDED,
|
|
||||||
"not THD_STATE_SUSPENDED");
|
|
||||||
|
|
||||||
(*trp)->p_u.rdymsg = msg;
|
|
||||||
chSchReadyI((thread_t *)*trp);
|
|
||||||
*trp = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Wakes up a thread waiting on a thread reference object.
|
|
||||||
* @note This function must reschedule, it can only be called from thread
|
|
||||||
* context.
|
|
||||||
*
|
|
||||||
* @param[in] trp a pointer to a thread reference object
|
|
||||||
* @param[in] msg the message code
|
|
||||||
*
|
|
||||||
* @iclass
|
|
||||||
*/
|
|
||||||
void osalThreadResumeS(thread_reference_t *trp, msg_t msg) {
|
|
||||||
|
|
||||||
if (*trp != NULL) {
|
|
||||||
thread_t *tp = (thread_t *)*trp;
|
|
||||||
|
|
||||||
chDbgAssert(tp->p_state == CH_STATE_SUSPENDED, "not THD_STATE_SUSPENDED");
|
|
||||||
|
|
||||||
*trp = NULL;
|
|
||||||
chSchWakeupS(tp, msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enqueues the caller thread.
|
|
||||||
* @details The caller thread is enqueued and put to sleep until it is
|
|
||||||
* dequeued or the specified timeouts expires.
|
|
||||||
*
|
|
||||||
* @param[in] tqp pointer to the threads queue object
|
|
||||||
* @param[in] time the timeout in system ticks, the special values are
|
|
||||||
* handled as follow:
|
|
||||||
* - @a TIME_INFINITE the thread enters an infinite sleep
|
|
||||||
* state.
|
|
||||||
* - @a TIME_IMMEDIATE the thread is not enqueued and
|
|
||||||
* the function returns @p MSG_TIMEOUT as if a timeout
|
|
||||||
* occurred.
|
|
||||||
* .
|
|
||||||
* @return The message from @p osalQueueWakeupOneI() or
|
|
||||||
* @p osalQueueWakeupAllI() functions.
|
|
||||||
* @retval RDY_TIMEOUT if the thread has not been dequeued within the
|
|
||||||
* specified timeout or if the function has been
|
|
||||||
* invoked with @p TIME_IMMEDIATE as timeout
|
|
||||||
* specification.
|
|
||||||
*
|
|
||||||
* @sclass
|
|
||||||
*/
|
|
||||||
msg_t osalQueueGoSleepTimeoutS(threads_queue_t *tqp, systime_t time) {
|
|
||||||
|
|
||||||
void wakeup(void *p) {
|
|
||||||
thread_t *tp = (thread_t *)p;
|
|
||||||
|
|
||||||
chSysUnlockFromISR();
|
|
||||||
tp->p_u.rdymsg = RDY_TIMEOUT;
|
|
||||||
chSchReadyI(queue_dequeue(tp));
|
|
||||||
chSysUnlockFromISR();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TIME_IMMEDIATE == time)
|
|
||||||
return MSG_TIMEOUT;
|
|
||||||
|
|
||||||
queue_insert(currp, tqp);
|
|
||||||
if (TIME_INFINITE == time)
|
|
||||||
chSchGoSleepS(CH_STATE_SUSPENDED);
|
|
||||||
else {
|
|
||||||
virtual_timer_t vt;
|
|
||||||
|
|
||||||
chVTDoSetI(&vt, time, wakeup, currp);
|
|
||||||
chSchGoSleepS(CH_STATE_SUSPENDED);
|
|
||||||
if (chVTIsArmedI(&vt))
|
|
||||||
chVTDoResetI(&vt);
|
|
||||||
}
|
|
||||||
return currp->p_u.rdymsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Dequeues and wakes up one thread from the queue, if any.
|
|
||||||
*
|
|
||||||
* @param[in] tqp pointer to the threads queue object
|
|
||||||
* @param[in] msg the message code
|
|
||||||
*
|
|
||||||
* @iclass
|
|
||||||
*/
|
|
||||||
void osalQueueWakeupOneI(threads_queue_t *tqp, msg_t msg) {
|
|
||||||
|
|
||||||
if (queue_notempty(tqp)) {
|
|
||||||
thread_t *tp = queue_fifo_remove(tqp);
|
|
||||||
tp->p_u.rdymsg = msg;
|
|
||||||
chSchReadyI(tp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Dequeues and wakes up all threads from the queue.
|
|
||||||
*
|
|
||||||
* @param[in] tqp pointer to the threads queue object
|
|
||||||
* @param[in] msg the message code
|
|
||||||
*
|
|
||||||
* @iclass
|
|
||||||
*/
|
|
||||||
void osalQueueWakeupAllI(threads_queue_t *tqp, msg_t msg) {
|
|
||||||
|
|
||||||
while (queue_notempty(tqp)) {
|
|
||||||
thread_t *tp = queue_fifo_remove(tqp);
|
|
||||||
tp->p_u.rdymsg = msg;
|
|
||||||
chSchReadyI(tp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -130,10 +130,12 @@ typedef uint32_t systime_t;
|
||||||
typedef uint32_t rtcnt_t;
|
typedef uint32_t rtcnt_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
* @brief Type of a thread reference.
|
* @brief Type of a thread reference.
|
||||||
*/
|
*/
|
||||||
typedef thread_t * thread_reference_t;
|
typedef thread_t * thread_reference_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/**
|
/**
|
||||||
|
@ -257,12 +259,6 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void osalInit(void);
|
void osalInit(void);
|
||||||
void osalSysHalt(const char *reason);
|
void osalSysHalt(const char *reason);
|
||||||
msg_t osalThreadSuspendS(thread_reference_t *trp);
|
|
||||||
void osalThreadResumeI(thread_reference_t *trp, msg_t msg);
|
|
||||||
void osalThreadResumeS(thread_reference_t *trp, msg_t msg);
|
|
||||||
msg_t osalQueueGoSleepTimeoutS(threads_queue_t *tqp, systime_t time);
|
|
||||||
void osalQueueWakeupOneI(threads_queue_t *tqp, msg_t msg);
|
|
||||||
void osalQueueWakeupAllI(threads_queue_t *tqp, msg_t msg);
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -391,6 +387,117 @@ static inline void osalThreadSleep(systime_t time) {
|
||||||
chThdSleep(time);
|
chThdSleep(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sends the current thread sleeping and sets a reference variable.
|
||||||
|
* @note This function must reschedule, it can only be called from thread
|
||||||
|
* context.
|
||||||
|
*
|
||||||
|
* @param[in] trp a pointer to a thread reference object
|
||||||
|
* @return The wake up message.
|
||||||
|
*
|
||||||
|
* @sclass
|
||||||
|
*/
|
||||||
|
static inline msg_t osalThreadSuspendS(thread_reference_t *trp) {
|
||||||
|
|
||||||
|
return osalThreadSuspendS(trp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Wakes up a thread waiting on a thread reference object.
|
||||||
|
* @note This function must not reschedule because it can be called from
|
||||||
|
* ISR context.
|
||||||
|
*
|
||||||
|
* @param[in] trp a pointer to a thread reference object
|
||||||
|
* @param[in] msg the message code
|
||||||
|
*
|
||||||
|
* @iclass
|
||||||
|
*/
|
||||||
|
static inline void osalThreadResumeI(thread_reference_t *trp, msg_t msg) {
|
||||||
|
|
||||||
|
chThreadResumeI(trp, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Wakes up a thread waiting on a thread reference object.
|
||||||
|
* @note This function must reschedule, it can only be called from thread
|
||||||
|
* context.
|
||||||
|
*
|
||||||
|
* @param[in] trp a pointer to a thread reference object
|
||||||
|
* @param[in] msg the message code
|
||||||
|
*
|
||||||
|
* @iclass
|
||||||
|
*/
|
||||||
|
static inline void osalThreadResumeS(thread_reference_t *trp, msg_t msg) {
|
||||||
|
|
||||||
|
chThreadResumeS(trp, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes a threads queue object.
|
||||||
|
*
|
||||||
|
* @param[out] tqp pointer to the threads queue object
|
||||||
|
*
|
||||||
|
* @init
|
||||||
|
*/
|
||||||
|
static inline void osalQueueObjectInit(threads_queue_t *tqp) {
|
||||||
|
|
||||||
|
queue_init(tqp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enqueues the caller thread.
|
||||||
|
* @details The caller thread is enqueued and put to sleep until it is
|
||||||
|
* dequeued or the specified timeouts expires.
|
||||||
|
*
|
||||||
|
* @param[in] tqp pointer to the threads queue object
|
||||||
|
* @param[in] time the timeout in system ticks, the special values are
|
||||||
|
* handled as follow:
|
||||||
|
* - @a TIME_INFINITE the thread enters an infinite sleep
|
||||||
|
* state.
|
||||||
|
* - @a TIME_IMMEDIATE the thread is not enqueued and
|
||||||
|
* the function returns @p MSG_TIMEOUT as if a timeout
|
||||||
|
* occurred.
|
||||||
|
* .
|
||||||
|
* @return The message from @p osalQueueWakeupOneI() or
|
||||||
|
* @p osalQueueWakeupAllI() functions.
|
||||||
|
* @retval RDY_TIMEOUT if the thread has not been dequeued within the
|
||||||
|
* specified timeout or if the function has been
|
||||||
|
* invoked with @p TIME_IMMEDIATE as timeout
|
||||||
|
* specification.
|
||||||
|
*
|
||||||
|
* @sclass
|
||||||
|
*/
|
||||||
|
static inline msg_t osalQueueGoSleepTimeoutS(threads_queue_t *tqp, systime_t time) {
|
||||||
|
|
||||||
|
return chQueueGoSleepTimeoutS(tqp, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Dequeues and wakes up one thread from the queue, if any.
|
||||||
|
*
|
||||||
|
* @param[in] tqp pointer to the threads queue object
|
||||||
|
* @param[in] msg the message code
|
||||||
|
*
|
||||||
|
* @iclass
|
||||||
|
*/
|
||||||
|
static inline void osalQueueWakeupOneI(threads_queue_t *tqp, msg_t msg) {
|
||||||
|
|
||||||
|
chQueueWakeupOneI(tqp, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Dequeues and wakes up all threads from the queue.
|
||||||
|
*
|
||||||
|
* @param[in] tqp pointer to the threads queue object
|
||||||
|
* @param[in] msg the message code
|
||||||
|
*
|
||||||
|
* @iclass
|
||||||
|
*/
|
||||||
|
static inline void osalQueueWakeupAllI(threads_queue_t *tqp, msg_t msg) {
|
||||||
|
|
||||||
|
chQueueWakeupAllI(tqp, msg);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes an event flags object.
|
* @brief Initializes an event flags object.
|
||||||
*
|
*
|
||||||
|
@ -494,18 +601,6 @@ static inline void osalMutexUnlock(mutex_t *mp) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initializes a threads queue object.
|
|
||||||
*
|
|
||||||
* @param[out] tqp pointer to the threads queue object
|
|
||||||
*
|
|
||||||
* @init
|
|
||||||
*/
|
|
||||||
static inline void osalQueueObjectInit(threads_queue_t *tqp) {
|
|
||||||
|
|
||||||
queue_init(tqp);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _OSAL_H_ */
|
#endif /* _OSAL_H_ */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file chlists.h
|
* @file chlists.h
|
||||||
* @brief Thread queues/lists inlined code.
|
* @brief Thread queues and lists header.
|
||||||
*
|
*
|
||||||
* @addtogroup internals
|
* @addtogroup queues_list
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -72,6 +72,16 @@
|
||||||
/* External declarations. */
|
/* External declarations. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
msg_t chQueueGoSleepTimeoutS(threads_queue_t *tqp, systime_t time);
|
||||||
|
void chQueueWakeupOneI(threads_queue_t *tqp, msg_t msg);
|
||||||
|
void chQueueWakeupAllI(threads_queue_t *tqp, msg_t msg);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module inline functions. */
|
/* Module inline functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -192,4 +202,16 @@ static inline thread_t *queue_dequeue(thread_t *tp) {
|
||||||
}
|
}
|
||||||
#endif /* CH_CFG_OPTIMIZE_SPEED */
|
#endif /* CH_CFG_OPTIMIZE_SPEED */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes a threads queue object.
|
||||||
|
*
|
||||||
|
* @param[out] tqp pointer to the threads queue object
|
||||||
|
*
|
||||||
|
* @init
|
||||||
|
*/
|
||||||
|
static inline void chQueueObjectInit(threads_queue_t *tqp) {
|
||||||
|
|
||||||
|
queue_init(tqp);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _CHLISTS_H_ */
|
#endif /* _CHLISTS_H_ */
|
||||||
|
|
|
@ -41,20 +41,20 @@
|
||||||
#define CH_STATE_CURRENT 1 /**< @brief Currently running. */
|
#define CH_STATE_CURRENT 1 /**< @brief Currently running. */
|
||||||
#define CH_STATE_WTSTART 2 /**< @brief Created but not started. */
|
#define CH_STATE_WTSTART 2 /**< @brief Created but not started. */
|
||||||
#define CH_STATE_SUSPENDED 3 /**< @brief Created in suspended state. */
|
#define CH_STATE_SUSPENDED 3 /**< @brief Created in suspended state. */
|
||||||
#define CH_STATE_WTSEM 4 /**< @brief Waiting on a semaphore. */
|
#define CH_STATE_QUEUED 4 /**< @brief Waiting on an I/O queue. */
|
||||||
#define CH_STATE_WTMTX 5 /**< @brief Waiting on a mutex. */
|
#define CH_STATE_WTSEM 5 /**< @brief Waiting on a semaphore. */
|
||||||
#define CH_STATE_WTCOND 6 /**< @brief Waiting on a condition
|
#define CH_STATE_WTMTX 6 /**< @brief Waiting on a mutex. */
|
||||||
|
#define CH_STATE_WTCOND 7 /**< @brief Waiting on a condition
|
||||||
variable. */
|
variable. */
|
||||||
#define CH_STATE_SLEEPING 7 /**< @brief Waiting in @p chThdSleep()
|
#define CH_STATE_SLEEPING 8 /**< @brief Waiting in @p chThdSleep()
|
||||||
or @p chThdSleepUntil(). */
|
or @p chThdSleepUntil(). */
|
||||||
#define CH_STATE_WTEXIT 8 /**< @brief Waiting in @p chThdWait(). */
|
#define CH_STATE_WTEXIT 9 /**< @brief Waiting in @p chThdWait(). */
|
||||||
#define CH_STATE_WTOREVT 9 /**< @brief Waiting for an event. */
|
#define CH_STATE_WTOREVT 10 /**< @brief Waiting for an event. */
|
||||||
#define CH_STATE_WTANDEVT 10 /**< @brief Waiting for several events. */
|
#define CH_STATE_WTANDEVT 11 /**< @brief Waiting for several events. */
|
||||||
#define CH_STATE_SNDMSGQ 11 /**< @brief Sending a message, in queue.*/
|
#define CH_STATE_SNDMSGQ 12 /**< @brief Sending a message, in queue.*/
|
||||||
#define CH_STATE_SNDMSG 12 /**< @brief Sent a message, waiting
|
#define CH_STATE_SNDMSG 13 /**< @brief Sent a message, waiting
|
||||||
answer. */
|
answer. */
|
||||||
#define CH_STATE_WTMSG 13 /**< @brief Waiting for a message. */
|
#define CH_STATE_WTMSG 14 /**< @brief Waiting for a message. */
|
||||||
#define CH_STATE_WTQUEUE 14 /**< @brief Waiting on an I/O queue. */
|
|
||||||
#define CH_STATE_FINAL 15 /**< @brief Thread terminated. */
|
#define CH_STATE_FINAL 15 /**< @brief Thread terminated. */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,9 +63,9 @@
|
||||||
* indexed using the numeric thread state values.
|
* indexed using the numeric thread state values.
|
||||||
*/
|
*/
|
||||||
#define CH_STATE_NAMES \
|
#define CH_STATE_NAMES \
|
||||||
"READY", "WTSTART", "CURRENT", "SUSPENDED", "WTSEM", "WTMTX", "WTCOND", \
|
"READY", "WTSTART", "CURRENT", "SUSPENDED", "QUEUED", "WTSEM", "WTMTX", \
|
||||||
"SLEEPING", "WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", "SNDMSG", \
|
"WTCOND", "SLEEPING", "WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", \
|
||||||
"WTMSG", "WTQUEUE", "FINAL"
|
"SNDMSG", "WTMSG", "FINAL"
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -93,6 +93,10 @@
|
||||||
/* Module data structures and types. */
|
/* Module data structures and types. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of a thread reference.
|
||||||
|
*/
|
||||||
|
typedef thread_t * thread_reference_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Thread function.
|
* @brief Thread function.
|
||||||
|
@ -161,8 +165,12 @@ extern "C" {
|
||||||
tprio_t prio, tfunc_t pf, void *arg);
|
tprio_t prio, tfunc_t pf, void *arg);
|
||||||
thread_t *chThdCreateStatic(void *wsp, size_t size,
|
thread_t *chThdCreateStatic(void *wsp, size_t size,
|
||||||
tprio_t prio, tfunc_t pf, void *arg);
|
tprio_t prio, tfunc_t pf, void *arg);
|
||||||
|
thread_t *chThdStart(thread_t *tp);
|
||||||
tprio_t chThdSetPriority(tprio_t newprio);
|
tprio_t chThdSetPriority(tprio_t newprio);
|
||||||
thread_t *chThdResume(thread_t *tp);
|
msg_t chThreadSuspendS(thread_reference_t *trp);
|
||||||
|
void chThreadResumeI(thread_reference_t *trp, msg_t msg);
|
||||||
|
void chThreadResumeS(thread_reference_t *trp, msg_t msg);
|
||||||
|
void chThreadResume(thread_reference_t *trp, msg_t msg);
|
||||||
void chThdTerminate(thread_t *tp);
|
void chThdTerminate(thread_t *tp);
|
||||||
void chThdSleep(systime_t time);
|
void chThdSleep(systime_t time);
|
||||||
void chThdSleepUntil(systime_t time);
|
void chThdSleepUntil(systime_t time);
|
||||||
|
@ -249,7 +257,7 @@ static inline bool chThdShouldTerminateX(void) {
|
||||||
*
|
*
|
||||||
* @param[in] tp pointer to the thread
|
* @param[in] tp pointer to the thread
|
||||||
*
|
*
|
||||||
* @xclass
|
* @iclass
|
||||||
*/
|
*/
|
||||||
static inline thread_t *chThdStartI(thread_t *tp) {
|
static inline thread_t *chThdStartI(thread_t *tp) {
|
||||||
|
|
||||||
|
|
|
@ -20,12 +20,9 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file chlists.c
|
* @file chlists.c
|
||||||
* @brief Thread queues/lists code.
|
* @brief Thread queues and lists code.
|
||||||
*
|
*
|
||||||
* @addtogroup internals
|
* @addtogroup queues_list
|
||||||
* @details All the functions present in this module, while public, are not
|
|
||||||
* OS APIs and should not be directly used in the user applications
|
|
||||||
* code.
|
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
|
@ -54,6 +51,80 @@
|
||||||
/* Module exported functions. */
|
/* Module exported functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enqueues the caller thread.
|
||||||
|
* @details The caller thread is enqueued and put to sleep until it is
|
||||||
|
* dequeued or the specified timeouts expires.
|
||||||
|
*
|
||||||
|
* @param[in] tqp pointer to the threads queue object
|
||||||
|
* @param[in] time the timeout in system ticks, the special values are
|
||||||
|
* handled as follow:
|
||||||
|
* - @a TIME_INFINITE the thread enters an infinite sleep
|
||||||
|
* state.
|
||||||
|
* - @a TIME_IMMEDIATE the thread is not enqueued and
|
||||||
|
* the function returns @p MSG_TIMEOUT as if a timeout
|
||||||
|
* occurred.
|
||||||
|
* .
|
||||||
|
* @return The message from @p osalQueueWakeupOneI() or
|
||||||
|
* @p osalQueueWakeupAllI() functions.
|
||||||
|
* @retval RDY_TIMEOUT if the thread has not been dequeued within the
|
||||||
|
* specified timeout or if the function has been
|
||||||
|
* invoked with @p TIME_IMMEDIATE as timeout
|
||||||
|
* specification.
|
||||||
|
*
|
||||||
|
* @sclass
|
||||||
|
*/
|
||||||
|
msg_t chQueueGoSleepTimeoutS(threads_queue_t *tqp, systime_t time) {
|
||||||
|
|
||||||
|
if (TIME_IMMEDIATE == time)
|
||||||
|
return RDY_TIMEOUT;
|
||||||
|
|
||||||
|
queue_insert(currp, tqp);
|
||||||
|
return chSchGoSleepTimeoutS(CH_STATE_QUEUED, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Dequeues and wakes up one thread from the queue, if any.
|
||||||
|
*
|
||||||
|
* @param[in] tqp pointer to the threads queue object
|
||||||
|
* @param[in] msg the message code
|
||||||
|
*
|
||||||
|
* @iclass
|
||||||
|
*/
|
||||||
|
void chQueueWakeupOneI(threads_queue_t *tqp, msg_t msg) {
|
||||||
|
|
||||||
|
if (queue_notempty(tqp)) {
|
||||||
|
thread_t *tp = queue_fifo_remove(tqp);
|
||||||
|
|
||||||
|
chDbgAssert(tp->p_state == CH_STATE_QUEUED,
|
||||||
|
"not CH_STATE_QUEUED");
|
||||||
|
|
||||||
|
tp->p_u.rdymsg = msg;
|
||||||
|
chSchReadyI(tp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Dequeues and wakes up all threads from the queue.
|
||||||
|
*
|
||||||
|
* @param[in] tqp pointer to the threads queue object
|
||||||
|
* @param[in] msg the message code
|
||||||
|
*
|
||||||
|
* @iclass
|
||||||
|
*/
|
||||||
|
void chQueueWakeupAllI(threads_queue_t *tqp, msg_t msg) {
|
||||||
|
|
||||||
|
while (queue_notempty(tqp)) {
|
||||||
|
thread_t *tp = queue_fifo_remove(tqp);
|
||||||
|
|
||||||
|
chDbgAssert(tp->p_state == CH_STATE_QUEUED,
|
||||||
|
"not CH_STATE_QUEUED");
|
||||||
|
|
||||||
|
tp->p_u.rdymsg = msg;
|
||||||
|
chSchReadyI(tp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if !CH_CFG_OPTIMIZE_SPEED || defined(__DOXYGEN__)
|
#if !CH_CFG_OPTIMIZE_SPEED || defined(__DOXYGEN__)
|
||||||
/**
|
/**
|
||||||
* @brief Inserts a thread into a priority ordered queue.
|
* @brief Inserts a thread into a priority ordered queue.
|
||||||
|
|
|
@ -65,30 +65,6 @@
|
||||||
/* Module local functions. */
|
/* Module local functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Puts the invoking thread into the queue's threads queue.
|
|
||||||
*
|
|
||||||
* @param[out] qp pointer to an @p io_queue_t structure
|
|
||||||
* @param[in] time the number of ticks before the operation timeouts,
|
|
||||||
* the following special values are allowed:
|
|
||||||
* - @a TIME_IMMEDIATE immediate timeout.
|
|
||||||
* - @a TIME_INFINITE no timeout.
|
|
||||||
* .
|
|
||||||
* @return A message specifying how the invoking thread has been
|
|
||||||
* released from threads queue.
|
|
||||||
* @retval Q_OK is the normal exit, thread signaled.
|
|
||||||
* @retval Q_RESET if the queue has been reset.
|
|
||||||
* @retval Q_TIMEOUT if the queue operation timed out.
|
|
||||||
*/
|
|
||||||
static msg_t qwait(io_queue_t *qp, systime_t time) {
|
|
||||||
|
|
||||||
if (TIME_IMMEDIATE == time)
|
|
||||||
return Q_TIMEOUT;
|
|
||||||
currp->p_u.wtobjp = qp;
|
|
||||||
queue_insert(currp, &qp->q_waiting);
|
|
||||||
return chSchGoSleepTimeoutS(CH_STATE_WTQUEUE, time);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module exported functions. */
|
/* Module exported functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -112,7 +88,7 @@ static msg_t qwait(io_queue_t *qp, systime_t time) {
|
||||||
void chIQObjectInit(input_queue_t *iqp, uint8_t *bp, size_t size,
|
void chIQObjectInit(input_queue_t *iqp, uint8_t *bp, size_t size,
|
||||||
qnotify_t infy, void *link) {
|
qnotify_t infy, void *link) {
|
||||||
|
|
||||||
queue_init(&iqp->q_waiting);
|
chQueueObjectInit(&iqp->q_waiting);
|
||||||
iqp->q_counter = 0;
|
iqp->q_counter = 0;
|
||||||
iqp->q_buffer = iqp->q_rdptr = iqp->q_wrptr = bp;
|
iqp->q_buffer = iqp->q_rdptr = iqp->q_wrptr = bp;
|
||||||
iqp->q_top = bp + size;
|
iqp->q_top = bp + size;
|
||||||
|
@ -137,8 +113,7 @@ void chIQResetI(input_queue_t *iqp) {
|
||||||
|
|
||||||
iqp->q_rdptr = iqp->q_wrptr = iqp->q_buffer;
|
iqp->q_rdptr = iqp->q_wrptr = iqp->q_buffer;
|
||||||
iqp->q_counter = 0;
|
iqp->q_counter = 0;
|
||||||
while (queue_notempty(&iqp->q_waiting))
|
chQueueWakeupAllI(&iqp->q_waiting, Q_RESET);
|
||||||
chSchReadyI(queue_fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_RESET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -166,8 +141,7 @@ msg_t chIQPutI(input_queue_t *iqp, uint8_t b) {
|
||||||
if (iqp->q_wrptr >= iqp->q_top)
|
if (iqp->q_wrptr >= iqp->q_top)
|
||||||
iqp->q_wrptr = iqp->q_buffer;
|
iqp->q_wrptr = iqp->q_buffer;
|
||||||
|
|
||||||
if (queue_notempty(&iqp->q_waiting))
|
chQueueWakeupOneI(&iqp->q_waiting, Q_OK);
|
||||||
chSchReadyI(queue_fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_OK;
|
|
||||||
|
|
||||||
return Q_OK;
|
return Q_OK;
|
||||||
}
|
}
|
||||||
|
@ -201,7 +175,7 @@ msg_t chIQGetTimeout(input_queue_t *iqp, systime_t time) {
|
||||||
|
|
||||||
while (chIQIsEmptyI(iqp)) {
|
while (chIQIsEmptyI(iqp)) {
|
||||||
msg_t msg;
|
msg_t msg;
|
||||||
if ((msg = qwait((io_queue_t *)iqp, time)) < Q_OK) {
|
if ((msg = chQueueGoSleepTimeoutS(&iqp->q_waiting, time)) < Q_OK) {
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
@ -253,7 +227,7 @@ size_t chIQReadTimeout(input_queue_t *iqp, uint8_t *bp,
|
||||||
nfy(iqp);
|
nfy(iqp);
|
||||||
|
|
||||||
while (chIQIsEmptyI(iqp)) {
|
while (chIQIsEmptyI(iqp)) {
|
||||||
if (qwait((io_queue_t *)iqp, time) != Q_OK) {
|
if (chQueueGoSleepTimeoutS(&iqp->q_waiting, time) != Q_OK) {
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -292,7 +266,7 @@ size_t chIQReadTimeout(input_queue_t *iqp, uint8_t *bp,
|
||||||
void chOQObjectInit(output_queue_t *oqp, uint8_t *bp, size_t size,
|
void chOQObjectInit(output_queue_t *oqp, uint8_t *bp, size_t size,
|
||||||
qnotify_t onfy, void *link) {
|
qnotify_t onfy, void *link) {
|
||||||
|
|
||||||
queue_init(&oqp->q_waiting);
|
chQueueObjectInit(&oqp->q_waiting);
|
||||||
oqp->q_counter = size;
|
oqp->q_counter = size;
|
||||||
oqp->q_buffer = oqp->q_rdptr = oqp->q_wrptr = bp;
|
oqp->q_buffer = oqp->q_rdptr = oqp->q_wrptr = bp;
|
||||||
oqp->q_top = bp + size;
|
oqp->q_top = bp + size;
|
||||||
|
@ -317,8 +291,7 @@ void chOQResetI(output_queue_t *oqp) {
|
||||||
|
|
||||||
oqp->q_rdptr = oqp->q_wrptr = oqp->q_buffer;
|
oqp->q_rdptr = oqp->q_wrptr = oqp->q_buffer;
|
||||||
oqp->q_counter = chQSizeI(oqp);
|
oqp->q_counter = chQSizeI(oqp);
|
||||||
while (queue_notempty(&oqp->q_waiting))
|
chQueueWakeupAllI(&oqp->q_waiting, Q_RESET);
|
||||||
chSchReadyI(queue_fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_RESET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -349,7 +322,7 @@ msg_t chOQPutTimeout(output_queue_t *oqp, uint8_t b, systime_t time) {
|
||||||
while (chOQIsFullI(oqp)) {
|
while (chOQIsFullI(oqp)) {
|
||||||
msg_t msg;
|
msg_t msg;
|
||||||
|
|
||||||
if ((msg = qwait((io_queue_t *)oqp, time)) < Q_OK) {
|
if ((msg = chQueueGoSleepTimeoutS(&oqp->q_waiting, time)) < Q_OK) {
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
@ -390,8 +363,7 @@ msg_t chOQGetI(output_queue_t *oqp) {
|
||||||
if (oqp->q_rdptr >= oqp->q_top)
|
if (oqp->q_rdptr >= oqp->q_top)
|
||||||
oqp->q_rdptr = oqp->q_buffer;
|
oqp->q_rdptr = oqp->q_buffer;
|
||||||
|
|
||||||
if (queue_notempty(&oqp->q_waiting))
|
chQueueWakeupOneI(&oqp->q_waiting, Q_OK);
|
||||||
chSchReadyI(queue_fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_OK;
|
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
@ -430,7 +402,7 @@ size_t chOQWriteTimeout(output_queue_t *oqp, const uint8_t *bp,
|
||||||
chSysLock();
|
chSysLock();
|
||||||
while (true) {
|
while (true) {
|
||||||
while (chOQIsFullI(oqp)) {
|
while (chOQIsFullI(oqp)) {
|
||||||
if (qwait((io_queue_t *)oqp, time) != Q_OK) {
|
if (chQueueGoSleepTimeoutS(&oqp->q_waiting, time) != Q_OK) {
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,22 +147,17 @@ static void wakeup(void *p) {
|
||||||
another thread with higher priority.*/
|
another thread with higher priority.*/
|
||||||
chSysUnlockFromISR();
|
chSysUnlockFromISR();
|
||||||
return;
|
return;
|
||||||
#if CH_CFG_USE_SEMAPHORES || CH_CFG_USE_QUEUES || \
|
|
||||||
(CH_CFG_USE_CONDVARS && CH_CFG_USE_CONDVARS_TIMEOUT)
|
|
||||||
#if CH_CFG_USE_SEMAPHORES
|
#if CH_CFG_USE_SEMAPHORES
|
||||||
case CH_STATE_WTSEM:
|
case CH_STATE_WTSEM:
|
||||||
chSemFastSignalI((semaphore_t *)tp->p_u.wtobjp);
|
chSemFastSignalI((semaphore_t *)tp->p_u.wtobjp);
|
||||||
/* Falls into, intentional. */
|
/* Falls into, intentional. */
|
||||||
#endif
|
#endif
|
||||||
#if CH_CFG_USE_QUEUES
|
|
||||||
case CH_STATE_WTQUEUE:
|
|
||||||
#endif
|
|
||||||
#if CH_CFG_USE_CONDVARS && CH_CFG_USE_CONDVARS_TIMEOUT
|
#if CH_CFG_USE_CONDVARS && CH_CFG_USE_CONDVARS_TIMEOUT
|
||||||
case CH_STATE_WTCOND:
|
case CH_STATE_WTCOND:
|
||||||
#endif
|
#endif
|
||||||
|
case CH_STATE_QUEUED:
|
||||||
/* States requiring dequeuing.*/
|
/* States requiring dequeuing.*/
|
||||||
queue_dequeue(tp);
|
queue_dequeue(tp);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
tp->p_u.rdymsg = RDY_TIMEOUT;
|
tp->p_u.rdymsg = RDY_TIMEOUT;
|
||||||
chSchReadyI(tp);
|
chSchReadyI(tp);
|
||||||
|
|
|
@ -222,6 +222,21 @@ thread_t *chThdCreateStatic(void *wsp, size_t size,
|
||||||
return tp;
|
return tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resumes a thread created with @p chThdCreateI().
|
||||||
|
*
|
||||||
|
* @param[in] tp pointer to the thread
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
thread_t *chThdStart(thread_t *tp) {
|
||||||
|
|
||||||
|
chSysLock();
|
||||||
|
tp = chThdStartI(tp);
|
||||||
|
chSysUnlock();
|
||||||
|
return tp;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Changes the running thread priority level then reschedules if
|
* @brief Changes the running thread priority level then reschedules if
|
||||||
* necessary.
|
* necessary.
|
||||||
|
@ -255,26 +270,84 @@ tprio_t chThdSetPriority(tprio_t newprio) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Resumes a suspended thread.
|
* @brief Sends the current thread sleeping and sets a reference variable.
|
||||||
* @pre The specified thread pointer must refer to an initialized thread
|
* @note This function must reschedule, it can only be called from thread
|
||||||
* in the @p CH_STATE_SUSPENDED state.
|
* context.
|
||||||
* @post The specified thread is immediately started or put in the ready
|
|
||||||
* list depending on the relative priority levels.
|
|
||||||
* @note Use this function to start threads created with @p chThdCreateI().
|
|
||||||
*
|
*
|
||||||
* @param[in] tp pointer to the thread
|
* @param[in] trp a pointer to a thread reference object
|
||||||
* @return The pointer to the thread.
|
* @return The wake up message.
|
||||||
|
*
|
||||||
|
* @sclass
|
||||||
|
*/
|
||||||
|
msg_t chThreadSuspendS(thread_reference_t *trp) {
|
||||||
|
|
||||||
|
chDbgAssert(*trp == NULL, "not NULL");
|
||||||
|
|
||||||
|
*trp = (thread_reference_t)chThdGetSelfX();
|
||||||
|
chSchGoSleepS(CH_STATE_SUSPENDED);
|
||||||
|
return chThdGetSelfX()->p_msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Wakes up a thread waiting on a thread reference object.
|
||||||
|
* @note This function must not reschedule because it can be called from
|
||||||
|
* ISR context.
|
||||||
|
*
|
||||||
|
* @param[in] trp a pointer to a thread reference object
|
||||||
|
* @param[in] msg the message code
|
||||||
|
*
|
||||||
|
* @iclass
|
||||||
|
*/
|
||||||
|
void chThreadResumeI(thread_reference_t *trp, msg_t msg) {
|
||||||
|
|
||||||
|
if (*trp != NULL) {
|
||||||
|
|
||||||
|
chDbgAssert((*trp)->p_state == CH_STATE_SUSPENDED,
|
||||||
|
"not THD_STATE_SUSPENDED");
|
||||||
|
|
||||||
|
(*trp)->p_u.rdymsg = msg;
|
||||||
|
chSchReadyI(*trp);
|
||||||
|
*trp = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Wakes up a thread waiting on a thread reference object.
|
||||||
|
* @note This function must reschedule, it can only be called from thread
|
||||||
|
* context.
|
||||||
|
*
|
||||||
|
* @param[in] trp a pointer to a thread reference object
|
||||||
|
* @param[in] msg the message code
|
||||||
|
*
|
||||||
|
* @iclass
|
||||||
|
*/
|
||||||
|
void chThreadResumeS(thread_reference_t *trp, msg_t msg) {
|
||||||
|
|
||||||
|
if (*trp != NULL) {
|
||||||
|
|
||||||
|
chDbgAssert((*trp)->p_state == CH_STATE_SUSPENDED,
|
||||||
|
"not THD_STATE_SUSPENDED");
|
||||||
|
|
||||||
|
*trp = NULL;
|
||||||
|
chSchWakeupS(*trp, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Wakes up a thread waiting on a thread reference object.
|
||||||
|
* @note This function must reschedule, it can only be called from thread
|
||||||
|
* context.
|
||||||
|
*
|
||||||
|
* @param[in] trp a pointer to a thread reference object
|
||||||
|
* @param[in] msg the message code
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
thread_t *chThdResume(thread_t *tp) {
|
void chThreadResume(thread_reference_t *trp, msg_t msg) {
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
chDbgAssert(tp->p_state == CH_STATE_SUSPENDED,
|
chThreadResumeS(trp, msg);
|
||||||
"thread not in CH_STATE_SUSPENDED state");
|
|
||||||
chSchWakeupS(tp, RDY_OK);
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
return tp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -97,11 +97,11 @@ static void thd2_execute(void) {
|
||||||
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-5, thread, "E");
|
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-5, thread, "E");
|
||||||
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread, "A");
|
threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, thread, "A");
|
||||||
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-2, thread, "B");
|
threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-2, thread, "B");
|
||||||
/* Done this way for coverage of chThdCreateI() and chThdResume().*/
|
/* Done this way for coverage of chThdCreateI() and chThdStart().*/
|
||||||
chSysLock();
|
chSysLock();
|
||||||
threads[2] = chThdCreateI(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread, "C");
|
threads[2] = chThdCreateI(wa[2], WA_SIZE, chThdGetPriorityX()-3, thread, "C");
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
chThdResume(threads[2]);
|
chThdStart(threads[2]);
|
||||||
test_wait_threads();
|
test_wait_threads();
|
||||||
test_assert_sequence(1, "ABCDE");
|
test_assert_sequence(1, "ABCDE");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue