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:
Giovanni Di Sirio 2021-10-13 09:27:02 +00:00
parent 5e00d074ad
commit de716ad412
3 changed files with 41 additions and 4 deletions

View File

@ -207,6 +207,10 @@ static void __sch_wakeup(virtual_timer_t *vtp, void *p) {
/* Falls through.*/ /* Falls through.*/
case CH_STATE_QUEUED: case CH_STATE_QUEUED:
/* Falls through.*/ /* 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) #if (CH_CFG_USE_CONDVARS == TRUE) && (CH_CFG_USE_CONDVARS_TIMEOUT == TRUE)
case CH_STATE_WTCOND: case CH_STATE_WTCOND:
#endif #endif

View File

@ -918,6 +918,29 @@ static void sb_undef_handler(struct port_extctx *ectxp) {
ectxp->r0 = SB_ERR_ENOSYS; 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. */ /* Module exported functions. */
/*===========================================================================*/ /*===========================================================================*/
@ -1005,15 +1028,20 @@ void sb_api_wait_message(struct port_extctx *ectxp) {
#if CH_CFG_USE_MESSAGES == TRUE #if CH_CFG_USE_MESSAGES == TRUE
sb_class_t *sbcp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p; sb_class_t *sbcp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
chSysLock();
if (sbcp->msg_tp == NULL) { 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); ectxp->r0 = (uint32_t)chMsgGet(sbcp->msg_tp);
} }
else { else {
chMsgRelease(sbcp->msg_tp, MSG_RESET); thread_t *tp = sbcp->msg_tp;
sbcp->msg_tp = NULL; sbcp->msg_tp = NULL;
chMsgReleaseS(tp, MSG_RESET);
ectxp->r0 = SB_ERR_EBUSY; ectxp->r0 = SB_ERR_EBUSY;
} }
chSysUnlock();
#else #else
ectxp->r0 = SB_ERR_NOT_IMPLEMENTED; ectxp->r0 = SB_ERR_NOT_IMPLEMENTED;
#endif #endif
@ -1023,14 +1051,19 @@ void sb_api_reply_message(struct port_extctx *ectxp) {
#if CH_CFG_USE_MESSAGES == TRUE #if CH_CFG_USE_MESSAGES == TRUE
sb_class_t *sbcp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p; sb_class_t *sbcp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
chSysLock();
if (sbcp->msg_tp != NULL) { if (sbcp->msg_tp != NULL) {
chMsgRelease(sbcp->msg_tp, (msg_t )ectxp->r0); thread_t *tp = sbcp->msg_tp;
sbcp->msg_tp = NULL; sbcp->msg_tp = NULL;
chMsgReleaseS(tp, (msg_t )ectxp->r0);
ectxp->r0 = SB_ERR_NOERROR; ectxp->r0 = SB_ERR_NOERROR;
} }
else { else {
ectxp->r0 = SB_ERR_EBUSY; ectxp->r0 = SB_ERR_EBUSY;
} }
chSysUnlock();
#else #else
ectxp->r0 = SB_ERR_NOT_IMPLEMENTED; ectxp->r0 = SB_ERR_NOT_IMPLEMENTED;
#endif #endif

View File

@ -201,7 +201,7 @@ msg_t sbSendMessageTimeout(sb_class_t *sbcp,
/* If a timeout occurred while the boxed thread already received the message /* If a timeout occurred while the boxed thread already received the message
then this thread needs to "unregister" as sender, the boxed error will then this thread needs to "unregister" as sender, the boxed error will
get SB_ERR_EBUSY when/if trying to reply.*/ 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; sbcp->msg_tp = NULL;
} }