From 89c12799e185423b6c571b78d5b44e11e67adf72 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 2 Jan 2011 10:13:43 +0000 Subject: Added new semaphore API chSemSetCounterI(). git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2569 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsem.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 3e1d2ce88..18ea9e996 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -311,6 +311,38 @@ void chSemSignalI(Semaphore *sp) { } } +/** + * @brief Sets the semaphore counter to the specified value. + * @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 structure + * @param[in] n the new value of the semaphore counter. The value must + * be non-negative. + * + * @iclass + */ +void chSemSetCounterI(Semaphore *sp, cnt_t n) { + cnt_t cnt; + + chDbgCheck((sp != NULL) && (n >= 0), "chSemSetCounterI"); + + chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || + ((sp->s_cnt < 0) && notempty(&sp->s_queue)), + "chSemSetCounterI(), #1", + "inconsistent semaphore"); + + cnt = sp->s_cnt; + sp->s_cnt = n; + while (++cnt <= 0) + chSchReadyI(lifo_remove(&sp->s_queue))->p_u.rdymsg = RDY_OK; +} + #if CH_USE_SEMSW /** * @brief Performs atomic signal and wait operations on two semaphores. -- cgit v1.2.3