ChibiOS  21.6.0
nil/src/chmsg.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/chmsg.c
22  * @brief Nil RTOS synchronous messages source file.
23  *
24  * @addtogroup NIL_MESSAGES
25  * @{
26  */
27 
28 #include "ch.h"
29 
30 #if (CH_CFG_USE_MESSAGES == 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 Sends a message to the specified thread.
58  * @details The sender is stopped until the receiver executes a
59  * @p chMsgRelease()after receiving the message.
60  *
61  * @param[in] tp the pointer to the thread
62  * @param[in] msg the message
63  * @return The answer message from @p chMsgRelease().
64  *
65  * @api
66  */
68  thread_t *ctp = nil.current;
69 
70  chDbgCheck(tp != NULL);
71 
72  chSysLock();
73  ctp->sntmsg = msg;
74  ctp->u1.tp = tp;
75  if (NIL_THD_IS_WTMSG(tp)) {
76  (void) chSchReadyI(tp, (msg_t)ctp);
77  }
79  chSysUnlock();
80 
81  return msg;
82 }
83 
84 /**
85  * @brief Suspends the thread and waits for an incoming message.
86  * @post After receiving a message the function @p chMsgGet() must be
87  * called in order to retrieve the message and then @p chMsgRelease()
88  * must be invoked in order to acknowledge the reception and send
89  * the answer.
90  * @note If the message is a pointer then you can assume that the data
91  * pointed by the message is stable until you invoke @p chMsgRelease()
92  * because the sending thread is suspended until then.
93  * @note The reference counter of the sender thread is not increased, the
94  * returned pointer is a temporary reference.
95  *
96  * @return A pointer to the thread carrying the message.
97  *
98  * @api
99  */
101  thread_t *tp;
102 
103  chSysLock();
104  tp = chMsgWaitS();
105  chSysUnlock();
106 
107  return tp;
108 }
109 
110 /**
111  * @brief Suspends the thread and waits for an incoming message or a
112  * timeout to occur.
113  * @post After receiving a message the function @p chMsgGet() must be
114  * called in order to retrieve the message and then @p chMsgRelease()
115  * must be invoked in order to acknowledge the reception and send
116  * the answer.
117  * @note If the message is a pointer then you can assume that the data
118  * pointed by the message is stable until you invoke @p chMsgRelease()
119  * because the sending thread is suspended until then.
120  * @note The reference counter of the sender thread is not increased, the
121  * returned pointer is a temporary reference.
122  *
123  * @param[in] timeout the number of ticks before the operation timeouts,
124  * the following special values are allowed:
125  * - @a TIME_IMMEDIATE immediate timeout.
126  * - @a TIME_INFINITE no timeout.
127  * .
128  * @return A pointer to the thread carrying the message.
129  * @retval NULL if a timeout occurred.
130  *
131  * @api
132  */
134  thread_t *tp;
135 
136  chSysLock();
137  tp = chMsgWaitTimeoutS(timeout);
138  chSysUnlock();
139 
140  return tp;
141 }
142 
143 /**
144  * @brief Suspends the thread and waits for an incoming message or a
145  * timeout to occur.
146  * @post After receiving a message the function @p chMsgGet() must be
147  * called in order to retrieve the message and then @p chMsgRelease()
148  * must be invoked in order to acknowledge the reception and send
149  * the answer.
150  * @note If the message is a pointer then you can assume that the data
151  * pointed by the message is stable until you invoke @p chMsgRelease()
152  * because the sending thread is suspended until then.
153  * @note The reference counter of the sender thread is not increased, the
154  * returned pointer is a temporary reference.
155  *
156  * @param[in] timeout the number of ticks before the operation timeouts,
157  * the following special values are allowed:
158  * - @a TIME_INFINITE no timeout.
159  * .
160  * @return A pointer to the thread carrying the message.
161  * @retval NULL if a timeout occurred.
162  *
163  * @sclass
164  */
166  thread_t *tp;
167 
168  chDbgCheckClassS();
169 
170  tp = nil_find_thread(NIL_STATE_SNDMSGQ, nil.current);
171  if (tp == NULL) {
173  if (msg != MSG_TIMEOUT) {
174  return (thread_t *)msg;
175  }
176  }
177 
178  return tp;
179 }
180 
181 /**
182  * @brief Releases a sender thread specifying a response message.
183  * @pre Invoke this function only after a message has been received
184  * using @p chMsgWait().
185  *
186  * @param[in] tp pointer to the thread
187  * @param[in] msg message to be returned to the sender
188  *
189  * @api
190  */
191 void chMsgRelease(thread_t *tp, msg_t msg) {
192 
193  chSysLock();
194  chDbgAssert(tp->state == NIL_STATE_SNDMSGQ, "invalid state");
195  chMsgReleaseS(tp, msg);
196  chSysUnlock();
197 }
198 
199 #endif /* CH_CFG_USE_MESSAGES == TRUE */
200 
201 /** @} */
chSchReadyI
thread_t * chSchReadyI(thread_t *tp)
Inserts a thread in the Ready List placing it behind its peers.
Definition: chschd.c:276
chMsgWaitS
thread_t * chMsgWaitS(void)
Suspends the thread and waits for an incoming message.
Definition: rt/src/chmsg.c:115
chDbgAssert
#define chDbgAssert(c, r)
Condition assertion.
Definition: chdebug.h:144
NIL_STATE_WTMSG
#define NIL_STATE_WTMSG
Waiting for a message.
Definition: nil/include/ch.h:151
msg_t
int32_t msg_t
Definition: chearly.h:88
chSchGoSleepTimeoutS
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:355
chMsgRelease
void chMsgRelease(thread_t *tp, msg_t msg)
Releases a sender thread specifying a response message.
Definition: nil/src/chmsg.c:191
chDbgCheck
#define chDbgCheck(c)
Function parameters check.
Definition: chdebug.h:118
chMsgWait
thread_t * chMsgWait(void)
Suspends the thread and waits for an incoming message.
Definition: nil/src/chmsg.c:100
nil
os_instance_t nil
System data structures.
Definition: ch.c:41
ch_thread
Structure representing a thread.
Definition: chobjects.h:156
TIME_INFINITE
#define TIME_INFINITE
Infinite interval specification for all functions with a timeout specification.
Definition: chtime.h:55
chMsgSend
msg_t chMsgSend(thread_t *tp, msg_t msg)
Sends a message to the specified thread.
Definition: nil/src/chmsg.c:67
chMsgReleaseS
#define chMsgReleaseS(tp, msg)
Releases the thread waiting on top of the messages queue.
Definition: nil/include/chmsg.h:97
sysinterval_t
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:119
chMsgWaitTimeoutS
thread_t * chMsgWaitTimeoutS(sysinterval_t timeout)
Suspends the thread and waits for an incoming message or a timeout to occur.
Definition: nil/src/chmsg.c:165
ch_thread::state
tstate_t state
Current thread state.
Definition: chobjects.h:206
MSG_TIMEOUT
#define MSG_TIMEOUT
Wakeup caused by a timeout condition.
Definition: chschd.h:40
nil_find_thread
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
NIL_STATE_SNDMSGQ
#define NIL_STATE_SNDMSGQ
Sending a message, in queue.
Definition: nil/include/ch.h:149
chSysUnlock
#define chSysUnlock()
Leaves the kernel lock state.
Definition: nil/include/ch.h:1053
chMsgWaitTimeout
thread_t * chMsgWaitTimeout(sysinterval_t timeout)
Suspends the thread and waits for an incoming message or a timeout to occur.
Definition: nil/src/chmsg.c:133
chSysLock
#define chSysLock()
Enters the kernel lock state.
Definition: nil/include/ch.h:1043