aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demos/STM32/RT-STM32L476-DISCOVERY/debug/RT-STM32L476-DISCOVERY (OpenOCD, Flash and Run).launch104
-rw-r--r--os/common/oslib/include/chmboxes.h4
-rw-r--r--os/nil/include/ch.h53
-rw-r--r--os/nil/src/ch.c126
-rw-r--r--test/nil/configuration.xml23
-rw-r--r--test/nil/source/test/test_sequence_004.c49
-rw-r--r--test/rt/.cproject2
-rw-r--r--test/rt/configuration.xml27
-rw-r--r--test/rt/source/test/test_sequence_008.c57
9 files changed, 305 insertions, 140 deletions
diff --git a/demos/STM32/RT-STM32L476-DISCOVERY/debug/RT-STM32L476-DISCOVERY (OpenOCD, Flash and Run).launch b/demos/STM32/RT-STM32L476-DISCOVERY/debug/RT-STM32L476-DISCOVERY (OpenOCD, Flash and Run).launch
index 7e863ea92..ee922c4a8 100644
--- a/demos/STM32/RT-STM32L476-DISCOVERY/debug/RT-STM32L476-DISCOVERY (OpenOCD, Flash and Run).launch
+++ b/demos/STM32/RT-STM32L476-DISCOVERY/debug/RT-STM32L476-DISCOVERY (OpenOCD, Flash and Run).launch
@@ -1,52 +1,52 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.cdt.debug.gdbjtag.launchConfigurationType">
-<stringAttribute key="bad_container_name" value="\RT-STM32L476-DISCOVERY\debug"/>
-<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="1"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="true"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="true"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value="set remotetimeout 20&#13;&#10;monitor reset init&#13;&#10;monitor sleep 50&#13;&#10;"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="Generic TCP/IP"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
-<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value=""/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="true"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
-<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
-<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
-<stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="arm-none-eabi-gdb"/>
-<stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="Standard"/>
-<stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
-<booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
-<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="arm-none-eabi-gdb"/>
-<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
-<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.FORMAT" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&lt;contentList/&gt;"/>
-<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;globalVariableList/&gt;&#10;"/>
-<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;memoryBlockExpressionList/&gt;&#10;"/>
-<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>
-<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="RT-STM32L476-DISCOVERY"/>
-<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
-<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="0.603687198"/>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/RT-STM32L476-DISCOVERY"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="4"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
-<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
-</listAttribute>
-</launchConfiguration>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.cdt.debug.gdbjtag.launchConfigurationType">
+<stringAttribute key="bad_container_name" value="\RT-STM32L476-DISCOVERY\debug"/>
+<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="1"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="true"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="true"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value="set remotetimeout 20&#13;&#10;monitor reset init&#13;&#10;monitor sleep 50&#13;&#10;"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="Generic TCP/IP"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
+<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value=""/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="true"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
+<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
+<stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="arm-none-eabi-gdb"/>
+<stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="Standard"/>
+<stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
+<booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
+<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="arm-none-eabi-gdb"/>
+<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
+<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.FORMAT" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&lt;contentList/&gt;"/>
+<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;globalVariableList/&gt;&#13;&#10;"/>
+<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;memoryBlockExpressionList/&gt;&#13;&#10;"/>
+<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>
+<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="RT-STM32L476-DISCOVERY"/>
+<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
+<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="0.603687198"/>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/RT-STM32L476-DISCOVERY"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="4"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+</listAttribute>
+</launchConfiguration>
diff --git a/os/common/oslib/include/chmboxes.h b/os/common/oslib/include/chmboxes.h
index fcb3225bc..c1f2d8bf6 100644
--- a/os/common/oslib/include/chmboxes.h
+++ b/os/common/oslib/include/chmboxes.h
@@ -159,10 +159,6 @@ static inline cnt_t chMBGetUsedCountI(mailbox_t *mbp) {
/**
* @brief Returns the number of free message slots into a mailbox.
- * @note Can be invoked in any system state but if invoked out of a locked
- * state then the returned value may change after reading.
- * @note The returned value can be less than zero when there are waiting
- * threads on the internal semaphore.
*
* @param[in] mbp the pointer to an initialized mailbox_t object
* @return The number of empty message slots.
diff --git a/os/nil/include/ch.h b/os/nil/include/ch.h
index cb32383cb..f21527c2d 100644
--- a/os/nil/include/ch.h
+++ b/os/nil/include/ch.h
@@ -111,12 +111,12 @@
executing. */
#define NIL_STATE_SLEEPING (tstate_t)1 /**< @brief Thread sleeping. */
#define NIL_STATE_SUSP (tstate_t)2 /**< @brief Thread suspended. */
-#define NIL_STATE_WTSEM (tstate_t)3 /**< @brief On semaphore. */
+#define NIL_STATE_WTQUEUE (tstate_t)3 /**< @brief On queue or semaph. */
#define NIL_STATE_WTOREVT (tstate_t)4 /**< @brief Waiting for events. */
#define NIL_THD_IS_READY(tr) ((tr)->state == NIL_STATE_READY)
#define NIL_THD_IS_SLEEPING(tr) ((tr)->state == NIL_STATE_SLEEPING)
#define NIL_THD_IS_SUSP(tr) ((tr)->state == NIL_STATE_SUSP)
-#define NIL_THD_IS_WTSEM(tr) ((tr)->state == NIL_STATE_WTSEM)
+#define NIL_THD_IS_WTQUEUE(tr) ((tr)->state == NIL_STATE_WTQUEUE)
#define NIL_THD_IS_WTOREVT(tr) ((tr)->state == NIL_STATE_WTOREVT)
/** @} */
@@ -474,18 +474,25 @@ typedef struct nil_thread thread_t;
#include "chcore.h"
-#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
/**
- * @brief Type of a structure representing a semaphore.
+ * @brief Structure representing a queue of threads.
*/
-typedef struct nil_semaphore semaphore_t;
+struct nil_threads_queue {
+ volatile cnt_t cnt; /**< @brief Threads Queue counter. */
+};
/**
- * @brief Structure representing a counting semaphore.
+ * @brief Type of a queue of threads.
*/
-struct nil_semaphore {
- volatile cnt_t cnt; /**< @brief Semaphore counter. */
-};
+typedef struct nil_threads_queue threads_queue_t;
+
+#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Type of a structure representing a semaphore.
+ * @note Semaphores are implemented on thread queues, the object is the
+ * same, the behavior is slightly different.
+ */
+typedef threads_queue_t semaphore_t;
#endif /* CH_CFG_USE_SEMAPHORES == TRUE */
/**
@@ -526,9 +533,7 @@ struct nil_thread {
msg_t msg; /**< @brief Wake-up message. */
void *p; /**< @brief Generic pointer. */
thread_reference_t *trp; /**< @brief Pointer to thread reference.*/
-#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
- semaphore_t *semp; /**< @brief Pointer to semaphore. */
-#endif
+ threads_queue_t *tqp; /**< @brief Pointer to thread queue. */
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
eventmask_t ewmask; /**< @brief Enabled events mask. */
#endif
@@ -1126,6 +1131,27 @@ struct nil_system {
(void) chSchGoSleepTimeoutS(NIL_STATE_SLEEPING, (abstime) - \
chVTGetSystemTimeX())
+/**
+ * @brief Initializes a threads queue object.
+ *
+ * @param[out] tqp pointer to the threads queue object
+ *
+ * @init
+ */
+#define chThdQueueObjectInit(tqp) ((tqp)->cnt = (cnt_t)0)
+
+/**
+ * @brief Evaluates to @p true if the specified queue is empty.
+ *
+ * @param[out] tqp pointer to the threads queue object
+ * @return The queue status.
+ * @retval false if the queue is not empty.
+ * @retval true if the queue is empty.
+ *
+ * @iclass
+ */
+#define chThdQueueIsEmptyI(tqp) ((bool)(tqp->cnt >= (cnt_t)0))
+
#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
/**
* @brief Initializes a semaphore with the specified counter value.
@@ -1341,6 +1367,9 @@ extern "C" {
void chThdResumeI(thread_reference_t *trp, msg_t msg);
void chThdSleep(systime_t timeout);
void chThdSleepUntil(systime_t abstime);
+ void chThdDoDequeueNextI(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);
#if CH_CFG_USE_SEMAPHORES == TRUE
msg_t chSemWaitTimeout(semaphore_t *sp, systime_t timeout);
msg_t chSemWaitTimeoutS(semaphore_t *sp, systime_t timeout);
diff --git a/os/nil/src/ch.c b/os/nil/src/ch.c
index 7fdf6812f..faf725164 100644
--- a/os/nil/src/ch.c
+++ b/os/nil/src/ch.c
@@ -328,10 +328,10 @@ void chSysTimerHandlerI(void) {
/* Did the timer reach zero?*/
if (--tp->timeout == (systime_t)0) {
- /* Timeout on semaphores requires a special handling because the
- semaphore counter must be incremented.*/
+ /* Timeout on queues/semaphores requires a special handling because
+ the counter must be incremented.*/
/*lint -save -e9013 [15.7] There is no else because it is not needed.*/
- if (NIL_THD_IS_WTSEM(tp)) {
+ if (NIL_THD_IS_WTQUEUE(tp)) {
tp->u1.semp->cnt++;
}
else if (NIL_THD_IS_SUSP(tp)) {
@@ -367,20 +367,16 @@ void chSysTimerHandlerI(void) {
tp->timeout = timeout;
if (timeout == (systime_t)0) {
-#if CH_CFG_USE_SEMAPHORES == TRUE
- /* Timeout on semaphores requires a special handling because the
- semaphore counter must be incremented.*/
- if (NIL_THD_IS_WTSEM(tp)) {
- tp->u1.semp->cnt++;
+ /* Timeout on thread queues requires a special handling because the
+ counter must be incremented.*/
+ if (NIL_THD_IS_WTQUEUE(tp)) {
+ tp->u1.tqp->cnt++;
}
else {
-#endif
if (NIL_THD_IS_SUSP(tp)) {
*tp->u1.trp = NULL;
}
-#if CH_CFG_USE_SEMAPHORES == TRUE
}
-#endif
(void) chSchReadyI(tp, MSG_TIMEOUT);
}
else {
@@ -761,6 +757,90 @@ void chThdSleepUntil(systime_t abstime) {
chSysUnlock();
}
+/**
+ * @brief Dequeues and wakes up one thread from the threads queue object.
+ * @details Dequeues one thread from the queue without checking if the queue
+ * is empty.
+ * @pre The queue must contain at least an object.
+ *
+ * @param[in] tqp pointer to the threads queue object
+ * @param[in] msg the message code
+ *
+ * @iclass
+ */
+void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg) {
+ thread_reference_t tr = nil.threads;
+
+ chDbgAssert(tqp->cnt > (cnt_t)0, "empty queue");
+
+ while (true) {
+ /* Is this thread waiting on this queue?*/
+ if (tr->u1.tqp == tqp) {
+ tqp->cnt++;
+
+ chDbgAssert(NIL_THD_IS_WTQUEUE(tr), "not waiting");
+
+ (void) chSchReadyI(tr, msg);
+ return;
+ }
+ tr++;
+
+ chDbgAssert(tr < &nil.threads[CH_CFG_NUM_THREADS],
+ "pointer out of range");
+ }
+}
+
+/**
+ * @brief Dequeues and wakes up one thread from the threads queue object,
+ * if any.
+ *
+ * @param[in] tqp pointer to the threads queue object
+ * @param[in] msg the message code
+ *
+ * @iclass
+ */
+void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg) {
+
+ chDbgCheckClassI();
+ chDbgCheck(tqp != NULL);
+
+ if (tqp->cnt <= (cnt_t)0) {
+ chThdDoDequeueNextI(tqp, msg);
+ }
+}
+
+/**
+ * @brief Dequeues and wakes up all threads from the threads queue object.
+ *
+ * @param[in] tqp pointer to the threads queue object
+ * @param[in] msg the message code
+ *
+ * @iclass
+ */
+void chThdDequeueAllI(threads_queue_t *tqp, msg_t msg) {
+ thread_t *tp;
+
+ chDbgCheckClassI();
+ chDbgCheck(tqp != NULL);
+
+ tp = nil.threads;
+ while (tqp->cnt < (cnt_t)0) {
+
+ chDbgAssert(tp < &nil.threads[CH_CFG_NUM_THREADS],
+ "pointer out of range");
+
+ /* Is this thread waiting on this queue?*/
+ if (tp->u1.tqp == tqp) {
+
+ chDbgAssert(NIL_THD_IS_WTQUEUE(tp), "not waiting");
+
+ tqp->cnt++;
+ (void) chSchReadyI(tp, msg);
+ }
+ tp++;
+ }
+}
+
#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
/**
* @brief Performs a wait operation on a semaphore with timeout specification.
@@ -823,8 +903,8 @@ msg_t chSemWaitTimeoutS(semaphore_t *sp, systime_t timeout) {
return MSG_TIMEOUT;
}
sp->cnt = cnt - (cnt_t)1;
- nil.current->u1.semp = sp;
- return chSchGoSleepTimeoutS(NIL_STATE_WTSEM, timeout);
+ nil.current->u1.tqp = (threads_queue_t *)sp;
+ return chSchGoSleepTimeoutS(NIL_STATE_WTQUEUE, timeout);
}
sp->cnt = cnt - (cnt_t)1;
return MSG_OK;
@@ -862,21 +942,7 @@ void chSemSignalI(semaphore_t *sp) {
chDbgCheck(sp != NULL);
if (++sp->cnt <= (cnt_t)0) {
- thread_reference_t tr = nil.threads;
- while (true) {
- /* Is this thread waiting on this semaphore?*/
- if (tr->u1.semp == sp) {
-
- chDbgAssert(NIL_THD_IS_WTSEM(tr), "not waiting");
-
- (void) chSchReadyI(tr, MSG_OK);
- return;
- }
- tr++;
-
- chDbgAssert(tr < &nil.threads[CH_CFG_NUM_THREADS],
- "pointer out of range");
- }
+ chThdDoDequeueNextI((threads_queue_t *)sp, MSG_OK);
}
}
@@ -932,9 +998,9 @@ void chSemResetI(semaphore_t *sp, cnt_t n) {
"pointer out of range");
/* Is this thread waiting on this semaphore?*/
- if (tp->u1.semp == sp) {
+ if (tp->u1.tqp == (threads_queue_t *)sp) {
- chDbgAssert(NIL_THD_IS_WTSEM(tp), "not waiting");
+ chDbgAssert(NIL_THD_IS_WTQUEUE(tp), "not waiting");
cnt++;
(void) chSchReadyI(tp, MSG_RESET);
diff --git a/test/nil/configuration.xml b/test/nil/configuration.xml
index f6d00873f..710e9a3be 100644
--- a/test/nil/configuration.xml
+++ b/test/nil/configuration.xml
@@ -650,6 +650,23 @@ test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");]]
</step>
<step>
<description>
+ <value>Testing the behavior of API when the mailbox is in reset state then return in active state.</value>
+ </description>
+ <tags>
+ <value />
+ </tags>
+ <code>
+ <value><![CDATA[msg1 = chMBPost(&mb1, (msg_t)0, TIME_INFINITE);
+test_assert(msg1 == MSG_RESET, "not in reset state");
+msg1 = chMBPostAhead(&mb1, (msg_t)0, TIME_INFINITE);
+test_assert(msg1 == MSG_RESET, "not in reset state");
+msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE);
+test_assert(msg1 == MSG_RESET, "not in reset state");
+chMBResumeX(&mb1);]]></value>
+ </code>
+ </step>
+ <step>
+ <description>
<value>Filling the mailbox using chMBPost() and chMBPostAhead() once, no errors expected.</value>
</description>
<tags>
@@ -771,7 +788,8 @@ chSysUnlock();
test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
test_assert_lock(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
-test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");]]></value>
+test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
+chMBResumeX(&mb1);]]></value>
</code>
</step>
<step>
@@ -922,7 +940,8 @@ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");]]></value>
<value />
</tags>
<code>
- <value><![CDATA[chMBReset(&mb1);]]></value>
+ <value><![CDATA[chMBReset(&mb1);;
+chMBResumeX(&mb1);]]></value>
</code>
</step>
<step>
diff --git a/test/nil/source/test/test_sequence_004.c b/test/nil/source/test/test_sequence_004.c
index 442aa49ba..c3f3463d3 100644
--- a/test/nil/source/test/test_sequence_004.c
+++ b/test/nil/source/test/test_sequence_004.c
@@ -70,15 +70,17 @@ static MAILBOX_DECL(mb1, mb_buffer, MB_SIZE);
* - [4.1.1] Testing the mailbox size.
* - [4.1.2] Resetting the mailbox, conditions are checked, no errors
* expected.
- * - [4.1.3] Filling the mailbox using chMBPost() and chMBPostAhead()
+ * - [4.1.3] Testing the behavior of API when the mailbox is in reset
+ * state then return in active state.
+ * - [4.1.4] Filling the mailbox using chMBPost() and chMBPostAhead()
* once, no errors expected.
- * - [4.1.4] Testing intermediate conditions. Data pointers must be
+ * - [4.1.5] Testing intermediate conditions. Data pointers must be
* aligned, semaphore counters are checked.
- * - [4.1.5] Emptying the mailbox using chMBFetch(), no errors
+ * - [4.1.6] Emptying the mailbox using chMBFetch(), no errors
* expected.
- * - [4.1.6] Posting and then fetching one more message, no errors
+ * - [4.1.7] Posting and then fetching one more message, no errors
* expected.
- * - [4.1.7] Testing final conditions. Data pointers must be aligned to
+ * - [4.1.8] Testing final conditions. Data pointers must be aligned to
* buffer start, semaphore counters are checked.
* .
*/
@@ -112,10 +114,23 @@ static void test_004_001_execute(void) {
test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
}
- /* [4.1.3] Filling the mailbox using chMBPost() and chMBPostAhead()
- once, no errors expected.*/
+ /* [4.1.3] Testing the behavior of API when the mailbox is in reset
+ state then return in active state.*/
test_set_step(3);
{
+ msg1 = chMBPost(&mb1, (msg_t)0, TIME_INFINITE);
+ test_assert(msg1 == MSG_RESET, "not in reset state");
+ msg1 = chMBPostAhead(&mb1, (msg_t)0, TIME_INFINITE);
+ test_assert(msg1 == MSG_RESET, "not in reset state");
+ msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE);
+ test_assert(msg1 == MSG_RESET, "not in reset state");
+ chMBResumeX(&mb1);
+ }
+
+ /* [4.1.4] Filling the mailbox using chMBPost() and chMBPostAhead()
+ once, no errors expected.*/
+ test_set_step(4);
+ {
for (i = 0; i < MB_SIZE - 1; i++) {
msg1 = chMBPost(&mb1, 'B' + i, TIME_INFINITE);
test_assert(msg1 == MSG_OK, "wrong wake-up message");
@@ -124,18 +139,18 @@ static void test_004_001_execute(void) {
test_assert(msg1 == MSG_OK, "wrong wake-up message");
}
- /* [4.1.4] Testing intermediate conditions. Data pointers must be
+ /* [4.1.5] Testing intermediate conditions. Data pointers must be
aligned, semaphore counters are checked.*/
- test_set_step(4);
+ test_set_step(5);
{
test_assert_lock(chMBGetFreeCountI(&mb1) == 0, "still empty");
test_assert_lock(chMBGetUsedCountI(&mb1) == MB_SIZE, "not full");
test_assert_lock(mb1.rdptr == mb1.wrptr, "pointers not aligned");
}
- /* [4.1.5] Emptying the mailbox using chMBFetch(), no errors
+ /* [4.1.6] Emptying the mailbox using chMBFetch(), no errors
expected.*/
- test_set_step(5);
+ test_set_step(6);
{
for (i = 0; i < MB_SIZE; i++) {
msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE);
@@ -145,9 +160,9 @@ static void test_004_001_execute(void) {
test_assert_sequence("ABCD", "wrong get sequence");
}
- /* [4.1.6] Posting and then fetching one more message, no errors
+ /* [4.1.7] Posting and then fetching one more message, no errors
expected.*/
- test_set_step(6);
+ test_set_step(7);
{
msg1 = chMBPost(&mb1, 'B' + i, TIME_INFINITE);
test_assert(msg1 == MSG_OK, "wrong wake-up message");
@@ -155,9 +170,9 @@ static void test_004_001_execute(void) {
test_assert(msg1 == MSG_OK, "wrong wake-up message");
}
- /* [4.1.7] Testing final conditions. Data pointers must be aligned to
+ /* [4.1.8] Testing final conditions. Data pointers must be aligned to
buffer start, semaphore counters are checked.*/
- test_set_step(7);
+ test_set_step(8);
{
test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
@@ -226,6 +241,7 @@ static void test_004_002_execute(void) {
test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
test_assert_lock(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
+ chMBResumeX(&mb1);
}
/* [4.2.3] Filling the mailbox using chMBPostI() and chMBPostAheadI()
@@ -352,7 +368,8 @@ static void test_004_003_execute(void) {
/* [4.3.3] Resetting the mailbox.*/
test_set_step(3);
{
- chMBReset(&mb1);
+ chMBReset(&mb1);;
+ chMBResumeX(&mb1);
}
/* [4.3.4] Testing chMBFetch() and chMBFetchI() timeout.*/
diff --git a/test/rt/.cproject b/test/rt/.cproject
index e849ada7d..e92ac3785 100644
--- a/test/rt/.cproject
+++ b/test/rt/.cproject
@@ -36,8 +36,8 @@
</toolChain>
</folderInfo>
<sourceEntries>
- <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="source"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="components"/>
+ <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="source"/>
</sourceEntries>
</configuration>
</storageModule>
diff --git a/test/rt/configuration.xml b/test/rt/configuration.xml
index f678671dc..49305faac 100644
--- a/test/rt/configuration.xml
+++ b/test/rt/configuration.xml
@@ -2985,6 +2985,23 @@ test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");]]
</step>
<step>
<description>
+ <value>Testing the behavior of API when the mailbox is in reset state then return in active state.</value>
+ </description>
+ <tags>
+ <value />
+ </tags>
+ <code>
+ <value><![CDATA[msg1 = chMBPost(&mb1, (msg_t)0, TIME_INFINITE);
+test_assert(msg1 == MSG_RESET, "not in reset state");
+msg1 = chMBPostAhead(&mb1, (msg_t)0, TIME_INFINITE);
+test_assert(msg1 == MSG_RESET, "not in reset state");
+msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE);
+test_assert(msg1 == MSG_RESET, "not in reset state");
+chMBResumeX(&mb1);]]></value>
+ </code>
+ </step>
+ <step>
+ <description>
<value>Filling the mailbox using chMBPost() and chMBPostAhead() once, no errors expected.</value>
</description>
<tags>
@@ -3094,7 +3111,7 @@ unsigned i;]]></value>
</step>
<step>
<description>
- <value>Resetting the mailbox, conditions are checked, no errors expected.</value>
+ <value>Resetting the mailbox, conditions are checked, no errors expected. The mailbox is then returned in active state.</value>
</description>
<tags>
<value />
@@ -3106,7 +3123,8 @@ chSysUnlock();
test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
test_assert_lock(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
-test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");]]></value>
+test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
+chMBResumeX(&mb1);]]></value>
</code>
</step>
<step>
@@ -3251,13 +3269,14 @@ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");]]></value>
</step>
<step>
<description>
- <value>Resetting the mailbox.</value>
+ <value>Resetting the mailbox. The mailbox is then returned in active state.</value>
</description>
<tags>
<value />
</tags>
<code>
- <value><![CDATA[chMBReset(&mb1);]]></value>
+ <value><![CDATA[chMBReset(&mb1);
+chMBResumeX(&mb1);]]></value>
</code>
</step>
<step>
diff --git a/test/rt/source/test/test_sequence_008.c b/test/rt/source/test/test_sequence_008.c
index fe8a1b93b..349e1a9d0 100644
--- a/test/rt/source/test/test_sequence_008.c
+++ b/test/rt/source/test/test_sequence_008.c
@@ -69,15 +69,17 @@ static MAILBOX_DECL(mb1, mb_buffer, MB_SIZE);
* - [8.1.1] Testing the mailbox size.
* - [8.1.2] Resetting the mailbox, conditions are checked, no errors
* expected.
- * - [8.1.3] Filling the mailbox using chMBPost() and chMBPostAhead()
+ * - [8.1.3] Testing the behavior of API when the mailbox is in reset
+ * state then return in active state.
+ * - [8.1.4] Filling the mailbox using chMBPost() and chMBPostAhead()
* once, no errors expected.
- * - [8.1.4] Testing intermediate conditions. Data pointers must be
+ * - [8.1.5] Testing intermediate conditions. Data pointers must be
* aligned, semaphore counters are checked.
- * - [8.1.5] Emptying the mailbox using chMBFetch(), no errors
+ * - [8.1.6] Emptying the mailbox using chMBFetch(), no errors
* expected.
- * - [8.1.6] Posting and then fetching one more message, no errors
+ * - [8.1.7] Posting and then fetching one more message, no errors
* expected.
- * - [8.1.7] Testing final conditions. Data pointers must be aligned to
+ * - [8.1.8] Testing final conditions. Data pointers must be aligned to
* buffer start, semaphore counters are checked.
* .
*/
@@ -111,10 +113,23 @@ static void test_008_001_execute(void) {
test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
}
- /* [8.1.3] Filling the mailbox using chMBPost() and chMBPostAhead()
- once, no errors expected.*/
+ /* [8.1.3] Testing the behavior of API when the mailbox is in reset
+ state then return in active state.*/
test_set_step(3);
{
+ msg1 = chMBPost(&mb1, (msg_t)0, TIME_INFINITE);
+ test_assert(msg1 == MSG_RESET, "not in reset state");
+ msg1 = chMBPostAhead(&mb1, (msg_t)0, TIME_INFINITE);
+ test_assert(msg1 == MSG_RESET, "not in reset state");
+ msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE);
+ test_assert(msg1 == MSG_RESET, "not in reset state");
+ chMBResumeX(&mb1);
+ }
+
+ /* [8.1.4] Filling the mailbox using chMBPost() and chMBPostAhead()
+ once, no errors expected.*/
+ test_set_step(4);
+ {
for (i = 0; i < MB_SIZE - 1; i++) {
msg1 = chMBPost(&mb1, 'B' + i, TIME_INFINITE);
test_assert(msg1 == MSG_OK, "wrong wake-up message");
@@ -123,18 +138,18 @@ static void test_008_001_execute(void) {
test_assert(msg1 == MSG_OK, "wrong wake-up message");
}
- /* [8.1.4] Testing intermediate conditions. Data pointers must be
+ /* [8.1.5] Testing intermediate conditions. Data pointers must be
aligned, semaphore counters are checked.*/
- test_set_step(4);
+ test_set_step(5);
{
test_assert_lock(chMBGetFreeCountI(&mb1) == 0, "still empty");
test_assert_lock(chMBGetUsedCountI(&mb1) == MB_SIZE, "not full");
test_assert_lock(mb1.rdptr == mb1.wrptr, "pointers not aligned");
}
- /* [8.1.5] Emptying the mailbox using chMBFetch(), no errors
+ /* [8.1.6] Emptying the mailbox using chMBFetch(), no errors
expected.*/
- test_set_step(5);
+ test_set_step(6);
{
for (i = 0; i < MB_SIZE; i++) {
msg1 = chMBFetch(&mb1, &msg2, TIME_INFINITE);
@@ -144,9 +159,9 @@ static void test_008_001_execute(void) {
test_assert_sequence("ABCD", "wrong get sequence");
}
- /* [8.1.6] Posting and then fetching one more message, no errors
+ /* [8.1.7] Posting and then fetching one more message, no errors
expected.*/
- test_set_step(6);
+ test_set_step(7);
{
msg1 = chMBPost(&mb1, 'B' + i, TIME_INFINITE);
test_assert(msg1 == MSG_OK, "wrong wake-up message");
@@ -154,9 +169,9 @@ static void test_008_001_execute(void) {
test_assert(msg1 == MSG_OK, "wrong wake-up message");
}
- /* [8.1.7] Testing final conditions. Data pointers must be aligned to
+ /* [8.1.8] Testing final conditions. Data pointers must be aligned to
buffer start, semaphore counters are checked.*/
- test_set_step(7);
+ test_set_step(8);
{
test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
@@ -182,7 +197,7 @@ static const testcase_t test_008_001 = {
* <h2>Test Steps</h2>
* - [8.2.1] Testing the mailbox size.
* - [8.2.2] Resetting the mailbox, conditions are checked, no errors
- * expected.
+ * expected. The mailbox is then returned in active state.
* - [8.2.3] Filling the mailbox using chMBPostI() and chMBPostAheadI()
* once, no errors expected.
* - [8.2.4] Testing intermediate conditions. Data pointers must be
@@ -215,7 +230,7 @@ static void test_008_002_execute(void) {
}
/* [8.2.2] Resetting the mailbox, conditions are checked, no errors
- expected.*/
+ expected. The mailbox is then returned in active state.*/
test_set_step(2);
{
chSysLock();
@@ -225,6 +240,7 @@ static void test_008_002_execute(void) {
test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
test_assert_lock(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
+ chMBResumeX(&mb1);
}
/* [8.2.3] Filling the mailbox using chMBPostI() and chMBPostAheadI()
@@ -304,7 +320,8 @@ static const testcase_t test_008_002 = {
* - [8.3.1] Filling the mailbox.
* - [8.3.2] Testing chMBPost(), chMBPostI(), chMBPostAhead() and
* chMBPostAheadI() timeout.
- * - [8.3.3] Resetting the mailbox.
+ * - [8.3.3] Resetting the mailbox. The mailbox is then returned in
+ * active state.
* - [8.3.4] Testing chMBFetch() and chMBFetchI() timeout.
* .
*/
@@ -348,10 +365,12 @@ static void test_008_003_execute(void) {
test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
}
- /* [8.3.3] Resetting the mailbox.*/
+ /* [8.3.3] Resetting the mailbox. The mailbox is then returned in
+ active state.*/
test_set_step(3);
{
chMBReset(&mb1);
+ chMBResumeX(&mb1);
}
/* [8.3.4] Testing chMBFetch() and chMBFetchI() timeout.*/