mirror of https://github.com/rusefi/ChibiOS.git
Threads queues completed in NIL.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10155 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
ca129dc5b4
commit
477baaed5a
|
@ -34,8 +34,8 @@
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
|
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
|
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList/>"/>
|
<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList/>"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <globalVariableList/> "/>
|
<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <globalVariableList/> "/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList/> "/>
|
<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList/> "/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>
|
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="NIL-STM32F303-DISCOVERY"/>
|
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="NIL-STM32F303-DISCOVERY"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
|
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
|
||||||
|
|
|
@ -48,68 +48,4 @@
|
||||||
/* Module exported functions. */
|
/* Module exported functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @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 osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg) {
|
|
||||||
semaphore_t *sp = &tqp->sem;
|
|
||||||
|
|
||||||
if (chSemGetCounterI(&tqp->sem) < (cnt_t)0) {
|
|
||||||
thread_t *tp = nil.threads;
|
|
||||||
while (true) {
|
|
||||||
/* Is this thread waiting on this semaphore?*/
|
|
||||||
if (tp->u1.semp == sp) {
|
|
||||||
sp->cnt++;
|
|
||||||
|
|
||||||
chDbgAssert(NIL_THD_IS_WTSEM(tp), "not waiting");
|
|
||||||
|
|
||||||
(void) chSchReadyI(tp, msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
tp++;
|
|
||||||
|
|
||||||
chDbgAssert(tp < &nil.threads[CH_CFG_NUM_THREADS],
|
|
||||||
"pointer out of range");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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 osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg) {
|
|
||||||
semaphore_t *sp = &tqp->sem;
|
|
||||||
thread_t *tp;
|
|
||||||
cnt_t cnt;
|
|
||||||
|
|
||||||
cnt = sp->cnt;
|
|
||||||
sp->cnt = (cnt_t)0;
|
|
||||||
tp = nil.threads;
|
|
||||||
while (cnt < (cnt_t)0) {
|
|
||||||
|
|
||||||
chDbgAssert(tp < &nil.threads[CH_CFG_NUM_THREADS],
|
|
||||||
"pointer out of range");
|
|
||||||
|
|
||||||
/* Is this thread waiting on this semaphore?*/
|
|
||||||
if (tp->u1.semp == sp) {
|
|
||||||
|
|
||||||
chDbgAssert(NIL_THD_IS_WTSEM(tp), "not waiting");
|
|
||||||
|
|
||||||
cnt++;
|
|
||||||
(void) chSchReadyI(tp, msg);
|
|
||||||
}
|
|
||||||
tp++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -219,6 +219,8 @@ struct event_source {
|
||||||
*/
|
*/
|
||||||
typedef semaphore_t mutex_t;
|
typedef semaphore_t mutex_t;
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
* @brief Type of a thread queue.
|
* @brief Type of a thread queue.
|
||||||
* @details A thread queue is a queue of sleeping threads, queued threads
|
* @details A thread queue is a queue of sleeping threads, queued threads
|
||||||
|
@ -227,8 +229,9 @@ typedef semaphore_t mutex_t;
|
||||||
* because there are no real threads.
|
* because there are no real threads.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
semaphore_t sem;
|
thread_reference_t tr;
|
||||||
} threads_queue_t;
|
} threads_queue_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module macros. */
|
/* Module macros. */
|
||||||
|
@ -444,8 +447,7 @@ typedef struct {
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg);
|
|
||||||
void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg);
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -766,7 +768,7 @@ static inline void osalThreadResumeS(thread_reference_t *trp, msg_t msg) {
|
||||||
*/
|
*/
|
||||||
static inline void osalThreadQueueObjectInit(threads_queue_t *tqp) {
|
static inline void osalThreadQueueObjectInit(threads_queue_t *tqp) {
|
||||||
|
|
||||||
chSemObjectInit(&tqp->sem, (cnt_t)0);
|
chThdQueueObjectInit(tqp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -795,7 +797,33 @@ static inline void osalThreadQueueObjectInit(threads_queue_t *tqp) {
|
||||||
static inline msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp,
|
static inline msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp,
|
||||||
systime_t time) {
|
systime_t time) {
|
||||||
|
|
||||||
return chSemWaitTimeoutS(&tqp->sem, time);
|
return chThdEnqueueTimeoutS(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 osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg) {
|
||||||
|
|
||||||
|
chThdDequeueNextI(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 osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg) {
|
||||||
|
|
||||||
|
chThdDequeueAllI(tqp, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -534,6 +534,9 @@ struct nil_thread {
|
||||||
void *p; /**< @brief Generic pointer. */
|
void *p; /**< @brief Generic pointer. */
|
||||||
thread_reference_t *trp; /**< @brief Pointer to thread reference.*/
|
thread_reference_t *trp; /**< @brief Pointer to thread reference.*/
|
||||||
threads_queue_t *tqp; /**< @brief Pointer to thread queue. */
|
threads_queue_t *tqp; /**< @brief Pointer to thread queue. */
|
||||||
|
#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
|
||||||
|
semaphore_t *semp; /**< @brief Pointer to semaphore. */
|
||||||
|
#endif
|
||||||
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
|
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
|
||||||
eventmask_t ewmask; /**< @brief Enabled events mask. */
|
eventmask_t ewmask; /**< @brief Enabled events mask. */
|
||||||
#endif
|
#endif
|
||||||
|
@ -911,6 +914,29 @@ struct nil_system {
|
||||||
#define US2RTC(freq, usec) (rtcnt_t)((((freq) + 999999UL) / 1000000UL) * (usec))
|
#define US2RTC(freq, usec) (rtcnt_t)((((freq) + 999999UL) / 1000000UL) * (usec))
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Threads queues
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief Data part of a static threads queue object initializer.
|
||||||
|
* @details This macro should be used when statically initializing a threads
|
||||||
|
* queue that is part of a bigger structure.
|
||||||
|
*
|
||||||
|
* @param[in] name the name of the threads queue variable
|
||||||
|
*/
|
||||||
|
#define _THREADS_QUEUE_DATA(name) {(cnt_t)0}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Static threads queue object initializer.
|
||||||
|
* @details Statically initialized threads queues require no explicit
|
||||||
|
* initialization using @p queue_init().
|
||||||
|
*
|
||||||
|
* @param[in] name the name of the threads queue variable
|
||||||
|
*/
|
||||||
|
#define _THREADS_QUEUE_DECL(name) \
|
||||||
|
threads_queue_t name = _THREADS_QUEUE_DATA(name)
|
||||||
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name Semaphores macros
|
* @name Semaphores macros
|
||||||
* @{
|
* @{
|
||||||
|
@ -1367,6 +1393,7 @@ extern "C" {
|
||||||
void chThdResumeI(thread_reference_t *trp, msg_t msg);
|
void chThdResumeI(thread_reference_t *trp, msg_t msg);
|
||||||
void chThdSleep(systime_t timeout);
|
void chThdSleep(systime_t timeout);
|
||||||
void chThdSleepUntil(systime_t abstime);
|
void chThdSleepUntil(systime_t abstime);
|
||||||
|
msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, systime_t timeout);
|
||||||
void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg);
|
void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg);
|
||||||
void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg);
|
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);
|
||||||
|
|
|
@ -757,6 +757,45 @@ void chThdSleepUntil(systime_t abstime) {
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enqueues the caller thread on a threads queue object.
|
||||||
|
* @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] timeout 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 MSG_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 chThdEnqueueTimeoutS(threads_queue_t *tqp, systime_t timeout) {
|
||||||
|
|
||||||
|
chDbgCheckClassS();
|
||||||
|
chDbgCheck(tqp != NULL);
|
||||||
|
|
||||||
|
chDbgAssert(tqp->cnt <= (cnt_t)0, "invalid counter");
|
||||||
|
|
||||||
|
if (TIME_IMMEDIATE == timeout) {
|
||||||
|
return MSG_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
tqp->cnt--;
|
||||||
|
nil.current->u1.tqp = tqp;
|
||||||
|
return chSchGoSleepTimeoutS(NIL_STATE_WTQUEUE, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Dequeues and wakes up one thread from the threads queue object.
|
* @brief Dequeues and wakes up one thread from the threads queue object.
|
||||||
* @details Dequeues one thread from the queue without checking if the queue
|
* @details Dequeues one thread from the queue without checking if the queue
|
||||||
|
@ -769,23 +808,23 @@ void chThdSleepUntil(systime_t abstime) {
|
||||||
* @iclass
|
* @iclass
|
||||||
*/
|
*/
|
||||||
void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg) {
|
void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg) {
|
||||||
thread_reference_t tr = nil.threads;
|
thread_t *tp = nil.threads;
|
||||||
|
|
||||||
chDbgAssert(tqp->cnt > (cnt_t)0, "empty queue");
|
chDbgAssert(tqp->cnt < (cnt_t)0, "empty queue");
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
/* Is this thread waiting on this queue?*/
|
/* Is this thread waiting on this queue?*/
|
||||||
if (tr->u1.tqp == tqp) {
|
if (tp->u1.tqp == tqp) {
|
||||||
tqp->cnt++;
|
tqp->cnt++;
|
||||||
|
|
||||||
chDbgAssert(NIL_THD_IS_WTQUEUE(tr), "not waiting");
|
chDbgAssert(NIL_THD_IS_WTQUEUE(tp), "not waiting");
|
||||||
|
|
||||||
(void) chSchReadyI(tr, msg);
|
(void) chSchReadyI(tp, msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tr++;
|
tp++;
|
||||||
|
|
||||||
chDbgAssert(tr < &nil.threads[CH_CFG_NUM_THREADS],
|
chDbgAssert(tp < &nil.threads[CH_CFG_NUM_THREADS],
|
||||||
"pointer out of range");
|
"pointer out of range");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -804,7 +843,7 @@ void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg) {
|
||||||
chDbgCheckClassI();
|
chDbgCheckClassI();
|
||||||
chDbgCheck(tqp != NULL);
|
chDbgCheck(tqp != NULL);
|
||||||
|
|
||||||
if (tqp->cnt <= (cnt_t)0) {
|
if (tqp->cnt < (cnt_t)0) {
|
||||||
chThdDoDequeueNextI(tqp, msg);
|
chThdDoDequeueNextI(tqp, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -903,7 +942,7 @@ msg_t chSemWaitTimeoutS(semaphore_t *sp, systime_t timeout) {
|
||||||
return MSG_TIMEOUT;
|
return MSG_TIMEOUT;
|
||||||
}
|
}
|
||||||
sp->cnt = cnt - (cnt_t)1;
|
sp->cnt = cnt - (cnt_t)1;
|
||||||
nil.current->u1.tqp = (threads_queue_t *)sp;
|
nil.current->u1.semp = sp;
|
||||||
return chSchGoSleepTimeoutS(NIL_STATE_WTQUEUE, timeout);
|
return chSchGoSleepTimeoutS(NIL_STATE_WTQUEUE, timeout);
|
||||||
}
|
}
|
||||||
sp->cnt = cnt - (cnt_t)1;
|
sp->cnt = cnt - (cnt_t)1;
|
||||||
|
@ -942,7 +981,21 @@ void chSemSignalI(semaphore_t *sp) {
|
||||||
chDbgCheck(sp != NULL);
|
chDbgCheck(sp != NULL);
|
||||||
|
|
||||||
if (++sp->cnt <= (cnt_t)0) {
|
if (++sp->cnt <= (cnt_t)0) {
|
||||||
chThdDoDequeueNextI((threads_queue_t *)sp, MSG_OK);
|
thread_t *tp = nil.threads;
|
||||||
|
while (true) {
|
||||||
|
/* Is this thread waiting on this semaphore?*/
|
||||||
|
if (tp->u1.semp == sp) {
|
||||||
|
|
||||||
|
chDbgAssert(NIL_THD_IS_WTQUEUE(tp), "not waiting");
|
||||||
|
|
||||||
|
(void) chSchReadyI(tp, MSG_OK);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tp++;
|
||||||
|
|
||||||
|
chDbgAssert(tp < &nil.threads[CH_CFG_NUM_THREADS],
|
||||||
|
"pointer out of range");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -998,7 +1051,7 @@ void chSemResetI(semaphore_t *sp, cnt_t n) {
|
||||||
"pointer out of range");
|
"pointer out of range");
|
||||||
|
|
||||||
/* Is this thread waiting on this semaphore?*/
|
/* Is this thread waiting on this semaphore?*/
|
||||||
if (tp->u1.tqp == (threads_queue_t *)sp) {
|
if (tp->u1.semp == sp) {
|
||||||
|
|
||||||
chDbgAssert(NIL_THD_IS_WTQUEUE(tp), "not waiting");
|
chDbgAssert(NIL_THD_IS_WTQUEUE(tp), "not waiting");
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,8 @@ a series of important improvements, new features have been added.
|
||||||
|
|
||||||
- Now uses the common ports architecture.
|
- Now uses the common ports architecture.
|
||||||
- Now uses the new shared RTOS components.
|
- Now uses the new shared RTOS components.
|
||||||
|
- Added implementation of thread queues directly in the kernel, removed it
|
||||||
|
from NIL OSAL.
|
||||||
- All new features are optional so there is no code size increase.
|
- All new features are optional so there is no code size increase.
|
||||||
- Enhanced source-level compatibility with RT.
|
- Enhanced source-level compatibility with RT.
|
||||||
- Enhanced debug features.
|
- Enhanced debug features.
|
||||||
|
|
Loading…
Reference in New Issue