Fixed SB messages with timeout.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14905 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
5e00d074ad
commit
de716ad412
|
@ -207,6 +207,10 @@ static void __sch_wakeup(virtual_timer_t *vtp, void *p) {
|
|||
/* Falls through.*/
|
||||
case CH_STATE_QUEUED:
|
||||
/* Falls through.*/
|
||||
#if CH_CFG_USE_MESSAGES == TRUE
|
||||
case CH_STATE_SNDMSGQ:
|
||||
/* Falls through.*/
|
||||
#endif
|
||||
#if (CH_CFG_USE_CONDVARS == TRUE) && (CH_CFG_USE_CONDVARS_TIMEOUT == TRUE)
|
||||
case CH_STATE_WTCOND:
|
||||
#endif
|
||||
|
|
|
@ -918,6 +918,29 @@ static void sb_undef_handler(struct port_extctx *ectxp) {
|
|||
ectxp->r0 = SB_ERR_ENOSYS;
|
||||
}
|
||||
|
||||
static thread_t *sb_msg_wait_timeout_s(sysinterval_t timeout) {
|
||||
thread_t *currtp = chThdGetSelfX();
|
||||
thread_t *tp;
|
||||
|
||||
chDbgCheckClassS();
|
||||
|
||||
/* The sender thread could have timed out in sbSendMessageTimeout() so
|
||||
repeating the wait if it did.*/
|
||||
do {
|
||||
if (!chMsgIsPendingI(currtp)) {
|
||||
if (chSchGoSleepTimeoutS(CH_STATE_WTMSG, timeout) != MSG_OK) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} while(ch_queue_isempty(&currtp->msgqueue));
|
||||
|
||||
/* Dequeuing the sender thread and returning it.*/
|
||||
tp = threadref(ch_queue_fifo_remove(&currtp->msgqueue));
|
||||
tp->state = CH_STATE_SNDMSG;
|
||||
|
||||
return tp;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
@ -1005,15 +1028,20 @@ void sb_api_wait_message(struct port_extctx *ectxp) {
|
|||
#if CH_CFG_USE_MESSAGES == TRUE
|
||||
sb_class_t *sbcp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
|
||||
|
||||
chSysLock();
|
||||
|
||||
if (sbcp->msg_tp == NULL) {
|
||||
sbcp->msg_tp = chMsgWait();
|
||||
sbcp->msg_tp = sb_msg_wait_timeout_s(TIME_INFINITE);
|
||||
ectxp->r0 = (uint32_t)chMsgGet(sbcp->msg_tp);
|
||||
}
|
||||
else {
|
||||
chMsgRelease(sbcp->msg_tp, MSG_RESET);
|
||||
thread_t *tp = sbcp->msg_tp;
|
||||
sbcp->msg_tp = NULL;
|
||||
chMsgReleaseS(tp, MSG_RESET);
|
||||
ectxp->r0 = SB_ERR_EBUSY;
|
||||
}
|
||||
|
||||
chSysUnlock();
|
||||
#else
|
||||
ectxp->r0 = SB_ERR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
|
@ -1023,14 +1051,19 @@ void sb_api_reply_message(struct port_extctx *ectxp) {
|
|||
#if CH_CFG_USE_MESSAGES == TRUE
|
||||
sb_class_t *sbcp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
|
||||
|
||||
chSysLock();
|
||||
|
||||
if (sbcp->msg_tp != NULL) {
|
||||
chMsgRelease(sbcp->msg_tp, (msg_t )ectxp->r0);
|
||||
thread_t *tp = sbcp->msg_tp;
|
||||
sbcp->msg_tp = NULL;
|
||||
chMsgReleaseS(tp, (msg_t )ectxp->r0);
|
||||
ectxp->r0 = SB_ERR_NOERROR;
|
||||
}
|
||||
else {
|
||||
ectxp->r0 = SB_ERR_EBUSY;
|
||||
}
|
||||
|
||||
chSysUnlock();
|
||||
#else
|
||||
ectxp->r0 = SB_ERR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
|
|
|
@ -201,7 +201,7 @@ msg_t sbSendMessageTimeout(sb_class_t *sbcp,
|
|||
/* If a timeout occurred while the boxed thread already received the message
|
||||
then this thread needs to "unregister" as sender, the boxed error will
|
||||
get SB_ERR_EBUSY when/if trying to reply.*/
|
||||
if (sbcp->msg_tp == ctp) {
|
||||
if ((msg == MSG_TIMEOUT) && (sbcp->msg_tp == ctp)) {
|
||||
sbcp->msg_tp = NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue