/** * @brief Performs atomic signal and wait operations on two semaphores. * * @param[in] sps pointer to a @p semaphore_t structure to be signaled * @param[in] spw pointer to a @p semaphore_t structure to wait on * @return A message specifying how the invoking thread has been * released from the semaphore. * @retval MSG_OK if the thread has not stopped on the semaphore or the * semaphore has been signaled. * @retval MSG_RESET if the semaphore has been reset using @p chSemReset(). * * @api */ msg_t chSemSignalWait(semaphore_t *sps, semaphore_t *spw) { msg_t msg; chDbgCheck((sps != NULL) && (spw != NULL)); chDbgAssert(((sps->s_cnt >= (cnt_t)0) && queue_isempty(&sps->s_queue)) || ((sps->s_cnt < (cnt_t)0) && queue_notempty(&sps->s_queue)), "inconsistent semaphore"); chDbgAssert(((spw->s_cnt >= (cnt_t)0) && queue_isempty(&spw->s_queue)) || ((spw->s_cnt < (cnt_t)0) && queue_notempty(&spw->s_queue)), "inconsistent semaphore"); chSysLock(); if (++sps->s_cnt <= (cnt_t)0) { chSchReadyI(queue_fifo_remove(&sps->s_queue))->p_u.rdymsg = MSG_OK; } if (--spw->s_cnt < (cnt_t)0) { thread_t *ctp = currp; sem_insert(ctp, &spw->s_queue); ctp->p_u.wtsemp = spw; chSchGoSleepS(CH_STATE_WTSEM); msg = ctp->p_u.rdymsg; } else { chSchRescheduleS(); msg = MSG_OK; } chSysUnlock(); return msg; }
/** * @brief Performs atomic signal and wait operations on two semaphores. * @pre The configuration option @p CH_USE_SEMSW must be enabled in order * to use this function. * * @param[in] sps pointer to a @p Semaphore structure to be signaled * @param[in] spw pointer to a @p Semaphore structure to be wait on * @return A message specifying how the invoking thread has been * released from the semaphore. * @retval RDY_OK if the thread has not stopped on the semaphore or the * semaphore has been signaled. * @retval RDY_RESET if the semaphore has been reset using @p chSemReset(). * * @api */ msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) { msg_t msg; chDbgCheck((sps != NULL) && (spw != NULL), "chSemSignalWait"); chDbgAssert(((sps->s_cnt >= 0) && isempty(&sps->s_queue)) || ((sps->s_cnt < 0) && notempty(&sps->s_queue)), "chSemSignalWait(), #1", "inconsistent semaphore"); chDbgAssert(((spw->s_cnt >= 0) && isempty(&spw->s_queue)) || ((spw->s_cnt < 0) && notempty(&spw->s_queue)), "chSemSignalWait(), #2", "inconsistent semaphore"); chSysLock(); if (++sps->s_cnt <= 0) chSchReadyI(fifo_remove(&sps->s_queue))->p_u.rdymsg = RDY_OK; if (--spw->s_cnt < 0) { Thread *ctp = currp; sem_insert(ctp, &spw->s_queue); ctp->p_u.wtobjp = spw; chSchGoSleepS(THD_STATE_WTSEM); msg = ctp->p_u.rdymsg; } else { chSchRescheduleS(); msg = RDY_OK; } chSysUnlock(); return msg; }
/** * @brief Performs a wait operation on a semaphore. * * @param[in] sp pointer to a @p semaphore_t structure * @return A message specifying how the invoking thread has been * released from the semaphore. * @retval MSG_OK if the thread has not stopped on the semaphore or the * semaphore has been signaled. * @retval MSG_RESET if the semaphore has been reset using @p chSemReset(). * * @sclass */ msg_t chSemWaitS(semaphore_t *sp) { chDbgCheckClassS(); chDbgCheck(sp != NULL); chDbgAssert(((sp->s_cnt >= 0) && queue_isempty(&sp->s_queue)) || ((sp->s_cnt < 0) && queue_notempty(&sp->s_queue)), "inconsistent semaphore"); if (--sp->s_cnt < 0) { currp->p_u.wtobjp = sp; sem_insert(currp, &sp->s_queue); chSchGoSleepS(CH_STATE_WTSEM); return currp->p_u.rdymsg; } return MSG_OK; }
/** * @brief Performs a wait operation on a semaphore. * * @param[in] sp pointer to a @p Semaphore structure * @return A message specifying how the invoking thread has been * released from the semaphore. * @retval RDY_OK if the thread has not stopped on the semaphore or the * semaphore has been signaled. * @retval RDY_RESET if the semaphore has been reset using @p chSemReset(). * * @sclass */ msg_t chSemWaitS(Semaphore *sp) { chDbgCheck(sp != NULL, "chSemWaitS"); chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || ((sp->s_cnt < 0) && notempty(&sp->s_queue)), "chSemWaitS(), #1", "inconsistent semaphore"); if (--sp->s_cnt < 0) { currp->p_u.wtobjp = sp; sem_insert(currp, &sp->s_queue); chSchGoSleepS(THD_STATE_WTSEM); return currp->p_u.rdymsg; } return RDY_OK; }
/** * @brief Performs a wait operation on a semaphore with timeout specification. * * @param[in] sp pointer to a @p semaphore_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 the semaphore. * @retval MSG_OK if the thread has not stopped on the semaphore or the * semaphore has been signaled. * @retval MSG_RESET if the semaphore has been reset using @p chSemReset(). * @retval MSG_TIMEOUT if the semaphore has not been signaled or reset within * the specified timeout. * * @sclass */ msg_t chSemWaitTimeoutS(semaphore_t *sp, systime_t time) { chDbgCheckClassS(); chDbgCheck(sp != NULL); chDbgAssert(((sp->s_cnt >= 0) && queue_isempty(&sp->s_queue)) || ((sp->s_cnt < 0) && queue_notempty(&sp->s_queue)), "inconsistent semaphore"); if (--sp->s_cnt < 0) { if (TIME_IMMEDIATE == time) { sp->s_cnt++; return MSG_TIMEOUT; } currp->p_u.wtobjp = sp; sem_insert(currp, &sp->s_queue); return chSchGoSleepTimeoutS(CH_STATE_WTSEM, time); } return MSG_OK; }
/** * @brief Performs a wait operation on a semaphore with timeout specification. * * @param[in] sp pointer to a @p Semaphore 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 the semaphore. * @retval RDY_OK if the thread has not stopped on the semaphore or the * semaphore has been signaled. * @retval RDY_RESET if the semaphore has been reset using @p chSemReset(). * @retval RDY_TIMEOUT if the semaphore has not been signaled or reset within * the specified timeout. * * @sclass */ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { chDbgCheck(sp != NULL, "chSemWaitTimeoutS"); chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || ((sp->s_cnt < 0) && notempty(&sp->s_queue)), "chSemWaitTimeoutS(), #1", "inconsistent semaphore"); if (--sp->s_cnt < 0) { if (TIME_IMMEDIATE == time) { sp->s_cnt++; return RDY_TIMEOUT; } currp->p_u.wtobjp = sp; sem_insert(currp, &sp->s_queue); return chSchGoSleepTimeoutS(THD_STATE_WTSEM, time); } return RDY_OK; }