The precondition in QXSemaphore::wait() asserts that the QXK scheduler is not locked. This is incorrect:
/// @pre this function must:
/// (1) NOT be called from an ISR;
/// (2) be called from an extended thread;
/// (3) the scheduler must NOT be locked and
/// (4) the thread must NOT be already blocked on any object.
///
Q_REQUIRE_ID(200, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */
&& (curr != static_cast<QXThread *>(0)) /* curr must be extended */
&& (QXK_attr_.lockPrio == static_cast<uint8_t>(0)) /* no lock */
&& (curr->m_temp.obj == static_cast<QMState *>(0))); // not blocked
Instead, the precondition should assert only that the thread calling QXSemaphore::wait() is not holding the lock (although the scheduler might be locked by some other thread):
/// @pre this function must:
/// (1) NOT be called from an ISR;
/// (2) be called from an extended thread;
/// (3) the thread must NOT be holding a scheduler lock
/// (4) the thread must NOT be already blocked on any object.
///
Q_REQUIRE_ID(200, (!QXK_ISR_CONTEXT_()) /* can't block inside an ISR */
&& (curr != static_cast<QXThread *>(0)) /* curr must be extended */
&& (QXK_attr_.lockHolder != curr->m_prio) /* not holding a lock */
&& (curr->m_temp.obj == static_cast<QMState *>(0))); // not blocked
This precondition is correct in all other blocking calls, such as QXMutex::lock(), QXThread::queueGet() and QXThread::delay().
This precondition is also correct in QSemaphore_wait() in QK/C. It seems that the precondition was simply not updated in QXK/C++.
--MMS
Fixed in QP/C 6.1.1.
--MMS