aboutsummaryrefslogtreecommitdiffstats
path: root/os/kernel
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-01-02 10:13:43 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-01-02 10:13:43 +0000
commit89c12799e185423b6c571b78d5b44e11e67adf72 (patch)
tree0a7ed39f08c078c4a61f957d037fa6cb1d4c5238 /os/kernel
parent90aa3805a2cbfb9e6d385d3051dd111be0a67569 (diff)
downloadChibiOS-89c12799e185423b6c571b78d5b44e11e67adf72.tar.gz
ChibiOS-89c12799e185423b6c571b78d5b44e11e67adf72.tar.bz2
ChibiOS-89c12799e185423b6c571b78d5b44e11e67adf72.zip
Added new semaphore API chSemSetCounterI().
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2569 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/kernel')
-rw-r--r--os/kernel/include/chsem.h1
-rw-r--r--os/kernel/src/chsem.c32
2 files changed, 33 insertions, 0 deletions
diff --git a/os/kernel/include/chsem.h b/os/kernel/include/chsem.h
index 17c6a03e3..efed15189 100644
--- a/os/kernel/include/chsem.h
+++ b/os/kernel/include/chsem.h
@@ -51,6 +51,7 @@ extern "C" {
msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time);
void chSemSignal(Semaphore *sp);
void chSemSignalI(Semaphore *sp);
+ void chSemSetCounterI(Semaphore *sp, cnt_t n);
#if CH_USE_SEMSW
msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw);
#endif
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.