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