New semaphore functions.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13076 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2019-10-05 11:58:54 +00:00
parent 4019d184a5
commit a3f67c5fc0
5 changed files with 102 additions and 20 deletions

View File

@ -65,6 +65,40 @@
*/
#define chSemObjectInit(sp, n) ((sp)->cnt = n)
/**
* @brief Performs a reset operation on the semaphore.
* @post After invoking this function all the threads waiting on the
* semaphore, if any, are released and the semaphore counter is set
* to the specified, non negative, value.
* @note This function implicitly sends @p MSG_RESET as message.
*
* @param[in] sp pointer to a @p semaphore_t structure
* @param[in] n the new value of the semaphore counter. The value must
* be non-negative.
*
* @api
*/
#define chSemReset(sp, n) chSemResetWithMessage(sp, n, MSG_RESET)
/**
* @brief Performs a reset operation on the semaphore.
* @post After invoking this function all the threads waiting on the
* semaphore, if any, are released and the semaphore counter is set
* to the specified, non negative, value.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
* @note This function implicitly sends @p MSG_RESET as message.
*
* @param[in] sp pointer to a @p semaphore_t structure
* @param[in] n the new value of the semaphore counter. The value must
* be non-negative.
*
* @iclass
*/
#define chSemResetI(sp, n) chSemResetWithMessageI(sp, n, MSG_RESET)
/**
* @brief Performs a wait operation on a semaphore.
*
@ -133,8 +167,8 @@ extern "C" {
msg_t chSemWaitTimeoutS(semaphore_t *sp, sysinterval_t timeout);
void chSemSignal(semaphore_t *sp);
void chSemSignalI(semaphore_t *sp);
void chSemReset(semaphore_t *sp, cnt_t n);
void chSemResetI(semaphore_t *sp, cnt_t n);
void chSemResetWithMessage(semaphore_t *sp, cnt_t n, msg_t msg);
void chSemResetWithMessageI(semaphore_t *sp, cnt_t n, msg_t msg);
#ifdef __cplusplus
}
#endif

View File

@ -169,17 +169,22 @@ void chSemSignalI(semaphore_t *sp) {
* @post After invoking this function all the threads waiting on the
* semaphore, if any, are released and the semaphore counter is set
* to the specified, non negative, value.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
*
* @param[in] sp pointer to a @p semaphore_t structure
* @param[in] n the new value of the semaphore counter. The value must
* be non-negative.
* @param[in] msg message to be sent
*
* @api
*/
void chSemReset(semaphore_t *sp, cnt_t n) {
void chSemResetWithMessage(semaphore_t *sp, cnt_t n, msg_t msg) {
chSysLock();
chSemResetI(sp, n);
chSemResetWithMessageI(sp, n, msg);
chSchRescheduleS();
chSysUnlock();
}
@ -197,10 +202,11 @@ void chSemReset(semaphore_t *sp, cnt_t n) {
* @param[in] sp pointer to a @p semaphore_t structure
* @param[in] n the new value of the semaphore counter. The value must
* be non-negative.
* @param[in] msg message to be sent
*
* @iclass
*/
void chSemResetI(semaphore_t *sp, cnt_t n) {
void chSemResetWithMessageI(semaphore_t *sp, cnt_t n, msg_t msg) {
cnt_t cnt;
chDbgCheckClassI();
@ -210,7 +216,7 @@ void chSemResetI(semaphore_t *sp, cnt_t n) {
sp->cnt = n;
/* Does nothing for cnt >= 0, calling anyway.*/
(void) nil_ready_all((void *)sp, cnt, MSG_RESET);
(void) nil_ready_all((void *)sp, cnt, msg);
}
#endif /* CH_CFG_USE_SEMAPHORES == TRUE */

View File

@ -89,8 +89,8 @@ typedef struct ch_semaphore {
extern "C" {
#endif
void chSemObjectInit(semaphore_t *sp, cnt_t n);
void chSemReset(semaphore_t *sp, cnt_t n);
void chSemResetI(semaphore_t *sp, cnt_t n);
void chSemResetWithMessage(semaphore_t *sp, cnt_t n, msg_t msg);
void chSemResetWithMessageI(semaphore_t *sp, cnt_t n, msg_t msg);
msg_t chSemWait(semaphore_t *sp);
msg_t chSemWaitS(semaphore_t *sp);
msg_t chSemWaitTimeout(semaphore_t *sp, sysinterval_t timeout);
@ -107,6 +107,46 @@ extern "C" {
/* Module inline functions. */
/*===========================================================================*/
/**
* @brief Performs a reset operation on the semaphore.
* @post After invoking this function all the threads waiting on the
* semaphore, if any, are released and the semaphore counter is set
* to the specified, non negative, value.
* @note This function implicitly sends @p MSG_RESET as message.
*
* @param[in] sp pointer to a @p semaphore_t structure
* @param[in] n the new value of the semaphore counter. The value must
* be non-negative.
*
* @api
*/
static inline void chSemReset(semaphore_t *sp, cnt_t n) {
chSemResetWithMessage(sp, n, MSG_RESET);
}
/**
* @brief Performs a reset operation on the semaphore.
* @post After invoking this function all the threads waiting on the
* semaphore, if any, are released and the semaphore counter is set
* to the specified, non negative, value.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
* @note This function implicitly sends @p MSG_RESET as message.
*
* @param[in] sp pointer to a @p semaphore_t structure
* @param[in] n the new value of the semaphore counter. The value must
* be non-negative.
*
* @iclass
*/
static inline void chSemResetI(semaphore_t *sp, cnt_t n) {
chSemResetWithMessageI(sp, n, MSG_RESET);
}
/**
* @brief Decreases the semaphore counter.
* @details This macro can be used when the counter is known to be positive.

View File

@ -107,20 +107,22 @@ void chSemObjectInit(semaphore_t *sp, cnt_t n) {
* @post After invoking this function all the threads waiting on the
* semaphore, if any, are released and the semaphore counter is set
* to the specified, non negative, value.
* @note The released threads can recognize they were waked up by a reset
* rather than a signal because the @p chSemWait() will return
* @p MSG_RESET instead of @p MSG_OK.
* @post This function does not reschedule so a call to a rescheduling
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
*
* @param[in] sp pointer to a @p semaphore_t structure
* @param[in] n the new value of the semaphore counter. The value must
* be non-negative.
* @param[in] msg message to be sent
*
* @api
*/
void chSemReset(semaphore_t *sp, cnt_t n) {
void chSemResetWithMessage(semaphore_t *sp, cnt_t n, msg_t msg) {
chSysLock();
chSemResetI(sp, n);
chSemResetWithMessageI(sp, n, msg);
chSchRescheduleS();
chSysUnlock();
}
@ -134,17 +136,15 @@ void chSemReset(semaphore_t *sp, cnt_t n) {
* function must be performed before unlocking the kernel. Note that
* interrupt handlers always reschedule on exit so an explicit
* reschedule must not be performed in ISRs.
* @note The released threads can recognize they were waked up by a reset
* rather than a signal because the @p chSemWait() will return
* @p MSG_RESET instead of @p MSG_OK.
*
* @param[in] sp pointer to a @p semaphore_t structure
* @param[in] n the new value of the semaphore counter. The value must
* be non-negative.
* @param[in] msg message to be sent
*
* @iclass
*/
void chSemResetI(semaphore_t *sp, cnt_t n) {
void chSemResetWithMessageI(semaphore_t *sp, cnt_t n, msg_t msg) {
cnt_t cnt;
chDbgCheckClassI();
@ -156,7 +156,7 @@ void chSemResetI(semaphore_t *sp, cnt_t n) {
cnt = sp->cnt;
sp->cnt = n;
while (++cnt <= (cnt_t)0) {
chSchReadyI(queue_lifo_remove(&sp->queue))->u.rdymsg = MSG_RESET;
chSchReadyI(queue_lifo_remove(&sp->queue))->u.rdymsg = msg;
}
}

View File

@ -74,9 +74,11 @@
*****************************************************************************
*** Next ***
- NEW: Added canTryAbortX() function to CAN driver, implemented
- NIL: New functions: chSemResetWithMessageI() and chSemResetWithMessage().
- RT: New functions: chSemResetWithMessageI() and chSemResetWithMessage().
- HAL: Added canTryAbortX() function to CAN driver, implemented
for STM32 CANv1.
- NEW: Added error handling to WSPI driver, now LLDs can report error
- HAL: Added error handling to WSPI driver, now LLDs can report error
conditions to upper layers.
- NEW: Added mcuconf.h generator for STM32G4x4.
- HAL: STM32 DMAv1 driver improvements and generalization, added support