ChibiOS 21.11.5
nil/src/chsem.c
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006-2026 Giovanni Di Sirio.
3
4 This file is part of ChibiOS.
5
6 ChibiOS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation version 3 of the License.
9
10 ChibiOS is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/**
20 * @file nil/src/chsem.c
21 * @brief Nil RTOS semaphores source file.
22 *
23 * @addtogroup NIL_SEMAPHORES
24 * @{
25 */
26
27#include "ch.h"
28
29#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
30
31/*===========================================================================*/
32/* Module local definitions. */
33/*===========================================================================*/
34
35/*===========================================================================*/
36/* Module exported variables. */
37/*===========================================================================*/
38
39/*===========================================================================*/
40/* Module local variables. */
41/*===========================================================================*/
42
43/*===========================================================================*/
44/* Module local functions. */
45/*===========================================================================*/
46
47/*===========================================================================*/
48/* Module interrupt handlers. */
49/*===========================================================================*/
50
51/*===========================================================================*/
52/* Module exported functions. */
53/*===========================================================================*/
54
55/**
56 * @brief Performs a wait operation on a semaphore with timeout specification.
57 *
58 * @param[in] sp pointer to a @p semaphore_t structure
59 * @param[in] timeout the number of ticks before the operation timeouts,
60 * the following special values are allowed:
61 * - @a TIME_IMMEDIATE immediate timeout.
62 * - @a TIME_INFINITE no timeout.
63 * .
64 * @return A message specifying how the invoking thread has been
65 * released from the semaphore.
66 * @retval NIL_MSG_OK if the thread has not stopped on the semaphore or the
67 * semaphore has been signaled.
68 * @retval NIL_MSG_RST if the semaphore has been reset using @p chSemReset().
69 * @retval NIL_MSG_TMO if the semaphore has not been signaled or reset within
70 * the specified timeout.
71 *
72 * @api
73 */
75 msg_t msg;
76
77 chSysLock();
78 msg = chSemWaitTimeoutS(sp, timeout);
80
81 return msg;
82}
83
84/**
85 * @brief Performs a wait operation on a semaphore with timeout specification.
86 *
87 * @param[in] sp pointer to a @p semaphore_t structure
88 * @param[in] timeout the number of ticks before the operation timeouts,
89 * the following special values are allowed:
90 * - @a TIME_IMMEDIATE immediate timeout.
91 * - @a TIME_INFINITE no timeout.
92 * .
93 * @return A message specifying how the invoking thread has been
94 * released from the semaphore.
95 * @retval NIL_MSG_OK if the thread has not stopped on the semaphore or the
96 * semaphore has been signaled.
97 * @retval NIL_MSG_RST if the semaphore has been reset using @p chSemReset().
98 * @retval NIL_MSG_TMO if the semaphore has not been signaled or reset within
99 * the specified timeout.
100 *
101 * @sclass
102 */
104
106 chDbgCheck(sp != NULL);
107
108 /* Note, the semaphore counter is a volatile variable so accesses are
109 manually optimized.*/
110 cnt_t cnt = sp->cnt;
111 if (cnt <= (cnt_t)0) {
112 if (TIME_IMMEDIATE == timeout) {
113
114 return MSG_TIMEOUT;
115 }
116 sp->cnt = cnt - (cnt_t)1;
117 nil.current->u1.semp = sp;
118
120 }
121 sp->cnt = cnt - (cnt_t)1;
122
123 return MSG_OK;
124}
125
126/**
127 * @brief Performs a signal operation on a semaphore.
128 *
129 * @param[in] sp pointer to a @p semaphore_t structure
130 *
131 * @api
132 */
134
135 chSysLock();
136 chSemSignalI(sp);
138 chSysUnlock();
139}
140
141/**
142 * @brief Performs a signal operation on a semaphore.
143 * @post This function does not reschedule so a call to a rescheduling
144 * function must be performed before unlocking the kernel. Note that
145 * interrupt handlers always reschedule on exit so an explicit
146 * reschedule must not be performed in ISRs.
147 *
148 * @param[in] sp pointer to a @p semaphore_t structure
149 *
150 * @iclass
151 */
153
155 chDbgCheck(sp != NULL);
156
157 if (++sp->cnt <= (cnt_t)0) {
158 thread_t *tp = nil_find_thread(NIL_STATE_WTQUEUE, (void *)sp);
159
160 chDbgAssert(tp != NULL, "thread not found");
161
162 (void) chSchReadyI(tp, MSG_OK);
163 }
164}
165
166/**
167 * @brief Performs a reset operation on the semaphore.
168 * @post After invoking this function all the threads waiting on the
169 * semaphore, if any, are released and the semaphore counter is set
170 * to the specified, non negative, value.
171 * @post This function does not reschedule so a call to a rescheduling
172 * function must be performed before unlocking the kernel. Note that
173 * interrupt handlers always reschedule on exit so an explicit
174 * reschedule must not be performed in ISRs.
175 *
176 * @param[in] sp pointer to a @p semaphore_t structure
177 * @param[in] n the new value of the semaphore counter. The value must
178 * be non-negative.
179 * @param[in] msg message to be sent
180 *
181 * @api
182 */
184
185 chSysLock();
186 chSemResetWithMessageI(sp, n, msg);
188 chSysUnlock();
189}
190
191/**
192 * @brief Performs a reset operation on the semaphore.
193 * @post After invoking this function all the threads waiting on the
194 * semaphore, if any, are released and the semaphore counter is set
195 * to the specified, non negative, value.
196 * @post This function does not reschedule so a call to a rescheduling
197 * function must be performed before unlocking the kernel. Note that
198 * interrupt handlers always reschedule on exit so an explicit
199 * reschedule must not be performed in ISRs.
200 *
201 * @param[in] sp pointer to a @p semaphore_t structure
202 * @param[in] n the new value of the semaphore counter. The value must
203 * be non-negative.
204 * @param[in] msg message to be sent
205 *
206 * @iclass
207 */
209 cnt_t cnt;
210
212 chDbgCheck((sp != NULL) && (n >= (cnt_t)0));
213
214 cnt = sp->cnt;
215 sp->cnt = n;
216
217 /* Does nothing for cnt >= 0, calling anyway.*/
218 (void) nil_ready_all((void *)sp, cnt, msg);
219}
220
221#endif /* CH_CFG_USE_SEMAPHORES == TRUE */
222
223/** @} */
#define chSysUnlock()
Leaves the kernel lock state.
os_instance_t nil
System data structures.
Definition ch.c:40
cnt_t nil_ready_all(void *p, cnt_t cnt, msg_t msg)
Puts in ready state all thread matching the specified status and associated object.
Definition ch.c:94
#define NIL_STATE_WTQUEUE
On queue or semaph.
#define chSysLock()
Enters the kernel lock state.
thread_t * nil_find_thread(tstate_t state, void *p)
Retrieves the highest priority thread in the specified state and associated to the specified object.
Definition ch.c:69
msg_t chSemWaitTimeout(semaphore_t *sp, sysinterval_t timeout)
Performs a wait operation on a semaphore with timeout specification.
void chSemSignal(semaphore_t *sp)
Performs a signal operation on a semaphore.
void chSemResetWithMessageI(semaphore_t *sp, cnt_t n, msg_t msg)
Performs a reset operation on the semaphore.
void chSemResetWithMessage(semaphore_t *sp, cnt_t n, msg_t msg)
Performs a reset operation on the semaphore.
msg_t chSemWaitTimeoutS(semaphore_t *sp, sysinterval_t timeout)
Performs a wait operation on a semaphore with timeout specification.
void chSemSignalI(semaphore_t *sp)
Performs a signal operation on a semaphore.
#define chDbgAssert(c, r)
Condition assertion.
Definition chdebug.h:143
#define chDbgCheck(c)
Function parameters check.
Definition chdebug.h:117
#define chDbgCheckClassS()
Definition chdebug.h:99
#define chDbgCheckClassI()
Definition chdebug.h:98
int32_t cnt_t
Definition chearly.h:91
int32_t msg_t
Definition chearly.h:87
struct ch_thread thread_t
Type of a thread structure.
Definition chearly.h:132
void chSchRescheduleS(void)
Performs a reschedule if a higher priority thread is runnable.
Definition chschd.c:457
#define MSG_OK
Normal wakeup message.
Definition chschd.h:38
thread_t * chSchReadyI(thread_t *tp)
Inserts a thread in the Ready List placing it behind its peers.
Definition chschd.c:279
#define MSG_TIMEOUT
Wakeup caused by a timeout condition.
Definition chschd.h:39
msg_t chSchGoSleepTimeoutS(tstate_t newstate, sysinterval_t timeout)
Puts the current thread to sleep into the specified state with timeout specification.
Definition chschd.c:358
struct ch_semaphore semaphore_t
Semaphore structure.
#define TIME_IMMEDIATE
Zero interval specification for some functions with a timeout specification.
Definition chtime.h:46
uint64_t sysinterval_t
Type of time interval.
Definition chtime.h:118
cnt_t cnt
The semaphore counter.