ChibiOS/RT  6.1.4
chthreads.h
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 rt/include/chthreads.h
22  * @brief Threads module macros and structures.
23  *
24  * @addtogroup threads
25  * @{
26  */
27 
28 #ifndef CHTHREADS_H
29 #define CHTHREADS_H
30 
31 /*lint -sem(chThdExit, r_no) -sem(chThdExitS, r_no)*/
32 
33 /*===========================================================================*/
34 /* Module constants. */
35 /*===========================================================================*/
36 
37 /*===========================================================================*/
38 /* Module pre-compile time settings. */
39 /*===========================================================================*/
40 
41 /*===========================================================================*/
42 /* Derived constants and error checks. */
43 /*===========================================================================*/
44 
45 /*===========================================================================*/
46 /* Module data structures and types. */
47 /*===========================================================================*/
48 
49 /**
50  * @brief Thread function.
51  */
52 typedef void (*tfunc_t)(void *p);
53 
54 /**
55  * @brief Type of a thread descriptor.
56  */
57 typedef struct {
58  /**
59  * @brief Thread name.
60  */
61  const char *name;
62  /**
63  * @brief Pointer to the working area base.
64  */
65  stkalign_t *wbase;
66  /**
67  * @brief End of the working area.
68  */
69  stkalign_t *wend;
70  /**
71  * @brief Thread priority.
72  */
73  tprio_t prio;
74  /**
75  * @brief Thread function pointer.
76  */
78  /**
79  * @brief Thread argument.
80  */
81  void *arg;
83 
84 /*===========================================================================*/
85 /* Module macros. */
86 /*===========================================================================*/
87 
88 /**
89  * @name Threads queues
90  * @{
91  */
92 /**
93  * @brief Data part of a static threads queue object initializer.
94  * @details This macro should be used when statically initializing a threads
95  * queue that is part of a bigger structure.
96  *
97  * @param[in] name the name of the threads queue variable
98  */
99 #define _THREADS_QUEUE_DATA(name) {_CH_QUEUE_DATA(name)}
100 
101 /**
102  * @brief Static threads queue object initializer.
103  * @details Statically initialized threads queues require no explicit
104  * initialization using @p queue_init().
105  *
106  * @param[in] name the name of the threads queue variable
107  */
108 #define THREADS_QUEUE_DECL(name) \
109  threads_queue_t name = _THREADS_QUEUE_DATA(name)
110 /** @} */
111 
112 /**
113  * @name Working Areas
114  * @{
115  */
116 /**
117  * @brief Calculates the total Working Area size.
118  *
119  * @param[in] n the stack size to be assigned to the thread
120  * @return The total used memory in bytes.
121  *
122  * @api
123  */
124 #define THD_WORKING_AREA_SIZE(n) \
125  MEM_ALIGN_NEXT(sizeof(thread_t) + PORT_WA_SIZE(n), PORT_STACK_ALIGN)
126 
127 /**
128  * @brief Static working area allocation.
129  * @details This macro is used to allocate a static thread working area
130  * aligned as both position and size.
131  *
132  * @param[in] s the name to be assigned to the stack array
133  * @param[in] n the stack size to be assigned to the thread
134  *
135  * @api
136  */
137 #define THD_WORKING_AREA(s, n) PORT_WORKING_AREA(s, n)
138 
139 /**
140  * @brief Base of a working area casted to the correct type.
141  *
142  * @param[in] s name of the working area
143  */
144 #define THD_WORKING_AREA_BASE(s) ((stkalign_t *)(s))
145 
146 /**
147  * @brief End of a working area casted to the correct type.
148  *
149  * @param[in] s name of the working area
150  */
151 #define THD_WORKING_AREA_END(s) (THD_WORKING_AREA_BASE(s) + \
152  (sizeof (s) / sizeof (stkalign_t)))
153 /** @} */
154 
155 /**
156  * @name Threads abstraction macros
157  * @{
158  */
159 /**
160  * @brief Thread declaration macro.
161  * @note Thread declarations should be performed using this macro because
162  * the port layer could define optimizations for thread functions.
163  */
164 #define THD_FUNCTION(tname, arg) PORT_THD_FUNCTION(tname, arg)
165 /** @} */
166 
167 /**
168  * @name Macro Functions
169  * @{
170  */
171 /**
172  * @brief Delays the invoking thread for the specified number of seconds.
173  * @note The specified time is rounded up to a value allowed by the real
174  * system tick clock.
175  * @note The maximum specifiable value is implementation dependent.
176  * @note Use of this macro for large values is not secure because
177  * integer overflows, make sure your value can be correctly
178  * converted.
179  *
180  * @param[in] sec time in seconds, must be different from zero
181  *
182  * @api
183  */
184 #define chThdSleepSeconds(sec) chThdSleep(TIME_S2I(sec))
185 
186 /**
187  * @brief Delays the invoking thread for the specified number of
188  * milliseconds.
189  * @note The specified time is rounded up to a value allowed by the real
190  * system tick clock.
191  * @note The maximum specifiable value is implementation dependent.
192  * @note Use of this macro for large values is not secure because
193  * integer overflows, make sure your value can be correctly
194  * converted.
195  *
196  * @param[in] msec time in milliseconds, must be different from zero
197  *
198  * @api
199  */
200 #define chThdSleepMilliseconds(msec) chThdSleep(TIME_MS2I(msec))
201 
202 /**
203  * @brief Delays the invoking thread for the specified number of
204  * microseconds.
205  * @note The specified time is rounded up to a value allowed by the real
206  * system tick clock.
207  * @note The maximum specifiable value is implementation dependent.
208  * @note Use of this macro for large values is not secure because
209  * integer overflows, make sure your value can be correctly
210  * converted.
211  *
212  * @param[in] usec time in microseconds, must be different from zero
213  *
214  * @api
215  */
216 #define chThdSleepMicroseconds(usec) chThdSleep(TIME_US2I(usec))
217 /** @} */
218 
219 /*===========================================================================*/
220 /* External declarations. */
221 /*===========================================================================*/
222 
223 #ifdef __cplusplus
224 extern "C" {
225 #endif
226  thread_t *_thread_init(thread_t *tp, const char *name, tprio_t prio);
227 #if CH_DBG_FILL_THREADS == TRUE
228  void _thread_memfill(uint8_t *startp, uint8_t *endp, uint8_t v);
229 #endif
234  thread_t *chThdCreateStatic(void *wsp, size_t size,
235  tprio_t prio, tfunc_t pf, void *arg);
237 #if CH_CFG_USE_REGISTRY == TRUE
239  void chThdRelease(thread_t *tp);
240 #endif
241  void chThdExit(msg_t msg);
242  void chThdExitS(msg_t msg);
243 #if CH_CFG_USE_WAITEXIT == TRUE
244  msg_t chThdWait(thread_t *tp);
245 #endif
246  tprio_t chThdSetPriority(tprio_t newprio);
247  void chThdTerminate(thread_t *tp);
248  msg_t chThdSuspendS(thread_reference_t *trp);
250  void chThdResumeI(thread_reference_t *trp, msg_t msg);
251  void chThdResumeS(thread_reference_t *trp, msg_t msg);
252  void chThdResume(thread_reference_t *trp, msg_t msg);
254  void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg);
255  void chThdDequeueAllI(threads_queue_t *tqp, msg_t msg);
256  void chThdSleep(sysinterval_t time);
257  void chThdSleepUntil(systime_t time);
259  void chThdYield(void);
260 #ifdef __cplusplus
261 }
262 #endif
263 
264 /*===========================================================================*/
265 /* Module inline functions. */
266 /*===========================================================================*/
267 
268 /**
269  * @brief Returns a pointer to the current @p thread_t.
270  *
271  * @return A pointer to the current thread.
272  *
273  * @xclass
274  */
275 static inline thread_t *chThdGetSelfX(void) {
276 
277  return ch.rlist.current;
278 }
279 
280 /**
281  * @brief Returns the current thread priority.
282  * @note Can be invoked in any context.
283  *
284  * @return The current thread priority.
285  *
286  * @xclass
287  */
288 static inline tprio_t chThdGetPriorityX(void) {
289 
290  return chThdGetSelfX()->hdr.pqueue.prio;
291 }
292 
293 /**
294  * @brief Returns the number of ticks consumed by the specified thread.
295  * @note This function is only available when the
296  * @p CH_DBG_THREADS_PROFILING configuration option is enabled.
297  *
298  * @param[in] tp pointer to the thread
299  * @return The number of consumed system ticks.
300  *
301  * @xclass
302  */
303 #if (CH_DBG_THREADS_PROFILING == TRUE) || defined(__DOXYGEN__)
304 static inline systime_t chThdGetTicksX(thread_t *tp) {
305 
306  return tp->time;
307 }
308 #endif
309 
310 #if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE) || \
311  defined(__DOXYGEN__)
312 /**
313  * @brief Returns the working area base of the specified thread.
314  *
315  * @param[in] tp pointer to the thread
316  * @return The working area base pointer.
317  *
318  * @xclass
319  */
320 static inline stkalign_t *chThdGetWorkingAreaX(thread_t *tp) {
321 
322  return tp->wabase;
323 }
324 #endif /* CH_DBG_ENABLE_STACK_CHECK == TRUE */
325 
326 /**
327  * @brief Verifies if the specified thread is in the @p CH_STATE_FINAL state.
328  *
329  * @param[in] tp pointer to the thread
330  * @retval true thread terminated.
331  * @retval false thread not terminated.
332  *
333  * @xclass
334  */
335 static inline bool chThdTerminatedX(thread_t *tp) {
336 
337  return (bool)(tp->state == CH_STATE_FINAL);
338 }
339 
340 /**
341  * @brief Verifies if the current thread has a termination request pending.
342  *
343  * @retval true termination request pending.
344  * @retval false termination request not pending.
345  *
346  * @xclass
347  */
348 static inline bool chThdShouldTerminateX(void) {
349 
350  return (bool)((chThdGetSelfX()->flags & CH_FLAG_TERMINATE) != (tmode_t)0);
351 }
352 
353 /**
354  * @brief Resumes a thread created with @p chThdCreateI().
355  *
356  * @param[in] tp pointer to the thread
357  * @return The pointer to the @p thread_t structure allocated for
358  * the thread into the working space area.
359  *
360  * @iclass
361  */
362 static inline thread_t *chThdStartI(thread_t *tp) {
363 
364  chDbgAssert(tp->state == CH_STATE_WTSTART, "wrong state");
365 
366  return chSchReadyI(tp);
367 }
368 
369 /**
370  * @brief Suspends the invoking thread for the specified number of ticks.
371  *
372  * @param[in] ticks the delay in system ticks, the special values are
373  * handled as follow:
374  * - @a TIME_INFINITE the thread enters an infinite sleep
375  * state.
376  * - @a TIME_IMMEDIATE this value is not allowed.
377  * .
378  *
379  * @sclass
380  */
381 static inline void chThdSleepS(sysinterval_t ticks) {
382 
383  chDbgCheck(ticks != TIME_IMMEDIATE);
384 
386 }
387 
388 /**
389  * @brief Initializes a threads queue object.
390  *
391  * @param[out] tqp pointer to the threads queue object
392  *
393  * @init
394  */
395 static inline void chThdQueueObjectInit(threads_queue_t *tqp) {
396 
397  ch_queue_init(&tqp->queue);
398 }
399 
400 /**
401  * @brief Evaluates to @p true if the specified queue is empty.
402  *
403  * @param[out] tqp pointer to the threads queue object
404  * @return The queue status.
405  * @retval false if the queue is not empty.
406  * @retval true if the queue is empty.
407  *
408  * @iclass
409  */
410 static inline bool chThdQueueIsEmptyI(threads_queue_t *tqp) {
411 
413 
414  return ch_queue_isempty(&tqp->queue);
415 }
416 
417 /**
418  * @brief Dequeues and wakes up one thread from the threads queue object.
419  * @details Dequeues one thread from the queue without checking if the queue
420  * is empty.
421  * @pre The queue must contain at least an object.
422  *
423  * @param[in] tqp pointer to the threads queue object
424  * @param[in] msg the message code
425  *
426  * @iclass
427  */
428 static inline void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg) {
429  thread_t *tp;
430 
431  chDbgAssert(ch_queue_notempty(&tqp->queue), "empty queue");
432 
433  tp = (thread_t *)ch_queue_fifo_remove(&tqp->queue);
434 
435  chDbgAssert(tp->state == CH_STATE_QUEUED, "invalid state");
436 
437  tp->u.rdymsg = msg;
438  (void) chSchReadyI(tp);
439 }
440 
441 #endif /* CHTHREADS_H */
442 
443 /** @} */
chThdCreateSuspended
thread_t * chThdCreateSuspended(const thread_descriptor_t *tdp)
Creates a new thread into a static memory area.
Definition: chthreads.c:216
chThdSuspendTimeoutS
msg_t chThdSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout)
Sends the current thread sleeping and sets a reference variable.
Definition: chthreads.c:765
chSchReadyI
thread_t * chSchReadyI(thread_t *tp)
Inserts a thread in the Ready List placing it behind its peers.
Definition: chschd.c:153
chThdQueueObjectInit
static void chThdQueueObjectInit(threads_queue_t *tqp)
Initializes a threads queue object.
Definition: chthreads.h:395
ch_thread::pqueue
ch_priority_queue_t pqueue
Threads ordered queues element.
Definition: chschd.h:138
CH_STATE_WTSTART
#define CH_STATE_WTSTART
Just created.
Definition: chschd.h:65
chThdQueueIsEmptyI
static bool chThdQueueIsEmptyI(threads_queue_t *tqp)
Evaluates to true if the specified queue is empty.
Definition: chthreads.h:410
ch_thread::rdymsg
msg_t rdymsg
Thread wakeup code.
Definition: chschd.h:201
chThdAddRef
thread_t * chThdAddRef(thread_t *tp)
Adds a reference to a thread object.
Definition: chthreads.c:401
ch_threads_queue
Structure representing a threads queue.
Definition: chschd.h:124
chThdCreateStatic
thread_t * chThdCreateStatic(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg)
Creates a new thread into a static memory area.
Definition: chthreads.c:323
systime_t
uint64_t systime_t
Type of system time.
Definition: chtime.h:107
chDbgAssert
#define chDbgAssert(c, r)
Condition assertion.
Definition: chdebug.h:127
thread_descriptor_t::wend
stkalign_t * wend
End of the working area.
Definition: chthreads.h:69
chThdCreateSuspendedI
thread_t * chThdCreateSuspendedI(const thread_descriptor_t *tdp)
Creates a new thread into a static memory area.
Definition: chthreads.c:167
tfunc_t
void(* tfunc_t)(void *p)
Thread function.
Definition: chthreads.h:52
chThdResumeS
void chThdResumeS(thread_reference_t *trp, msg_t msg)
Wakes up a thread waiting on a thread reference object.
Definition: chthreads.c:813
chThdCreateI
thread_t * chThdCreateI(const thread_descriptor_t *tdp)
Creates a new thread into a static memory area.
Definition: chthreads.c:259
ch_queue_notempty
static bool ch_queue_notempty(const ch_queue_t *qp)
Evaluates to true if the specified queue is not empty.
Definition: chlists.h:234
ch_queue_isempty
static bool ch_queue_isempty(const ch_queue_t *qp)
Evaluates to true if the specified queue is empty.
Definition: chlists.h:221
chThdGetWorkingAreaX
static stkalign_t * chThdGetWorkingAreaX(thread_t *tp)
Returns the working area base of the specified thread.
Definition: chthreads.h:320
chThdStartI
static thread_t * chThdStartI(thread_t *tp)
Resumes a thread created with chThdCreateI().
Definition: chthreads.h:362
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:258
thread_descriptor_t::wbase
stkalign_t * wbase
Pointer to the working area base.
Definition: chthreads.h:65
chThdDequeueAllI
void chThdDequeueAllI(threads_queue_t *tqp, msg_t msg)
Dequeues and wakes up all threads from the threads queue object.
Definition: chthreads.c:900
chThdTerminate
void chThdTerminate(thread_t *tp)
Requests a thread termination.
Definition: chthreads.c:633
chThdEnqueueTimeoutS
msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout)
Enqueues the caller thread on a threads queue object.
Definition: chthreads.c:865
chDbgCheck
#define chDbgCheck(c)
Function parameters check.
Definition: chdebug.h:101
chThdTerminatedX
static bool chThdTerminatedX(thread_t *tp)
Verifies if the specified thread is in the CH_STATE_FINAL state.
Definition: chthreads.h:335
TIME_IMMEDIATE
#define TIME_IMMEDIATE
Zero interval specification for some functions with a timeout specification.
Definition: chtime.h:47
thread_descriptor_t::funcp
tfunc_t funcp
Thread function pointer.
Definition: chthreads.h:77
chThdResumeI
void chThdResumeI(thread_reference_t *trp, msg_t msg)
Wakes up a thread waiting on a thread reference object.
Definition: chthreads.c:790
ch_thread
Structure representing a thread.
Definition: chschd.h:134
_thread_memfill
void _thread_memfill(uint8_t *startp, uint8_t *endp, uint8_t v)
Memory fill utility.
Definition: chthreads.c:136
ch_thread::wabase
stkalign_t * wabase
Working area base address.
Definition: chschd.h:160
chThdWait
msg_t chThdWait(thread_t *tp)
Blocks the execution of the invoking thread until the specified thread terminates then the exit code ...
Definition: chthreads.c:559
ch_queue_fifo_remove
static ch_queue_t * ch_queue_fifo_remove(ch_queue_t *qp)
Removes the first-out element from a queue and returns it.
Definition: chlists.h:265
CH_STATE_FINAL
#define CH_STATE_FINAL
Thread terminated.
Definition: chschd.h:81
ch_thread::u
union ch_thread::@1 u
State-specific fields.
thread_descriptor_t
Type of a thread descriptor.
Definition: chthreads.h:57
chThdShouldTerminateX
static bool chThdShouldTerminateX(void)
Verifies if the current thread has a termination request pending.
Definition: chthreads.h:348
chThdSetPriority
tprio_t chThdSetPriority(tprio_t newprio)
Changes the running thread priority level then reschedules if necessary.
Definition: chthreads.c:598
thread_descriptor_t::arg
void * arg
Thread argument.
Definition: chthreads.h:81
chThdSuspendS
msg_t chThdSuspendS(thread_reference_t *trp)
Sends the current thread sleeping and sets a reference variable.
Definition: chthreads.c:734
chThdDoDequeueNextI
static void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg)
Dequeues and wakes up one thread from the threads queue object.
Definition: chthreads.h:428
ch_queue_init
static void ch_queue_init(ch_queue_t *qp)
Queue initialization.
Definition: chlists.h:207
chDbgCheckClassI
void chDbgCheckClassI(void)
I-class functions context check.
Definition: chdebug.c:233
CH_FLAG_TERMINATE
#define CH_FLAG_TERMINATE
Termination requested flag.
Definition: chschd.h:105
_thread_init
thread_t * _thread_init(thread_t *tp, const char *name, tprio_t prio)
Initializes a thread structure.
Definition: chthreads.c:88
CH_STATE_SLEEPING
#define CH_STATE_SLEEPING
Sleeping.
Definition: chschd.h:71
ch_thread::time
volatile systime_t time
Thread consumed time in ticks.
Definition: chschd.h:187
chThdYield
void chThdYield(void)
Yields the time slot.
Definition: chthreads.c:717
chThdSleepUntilWindowed
systime_t chThdSleepUntilWindowed(systime_t prev, systime_t next)
Suspends the invoking thread until the system time arrives to the specified value.
Definition: chthreads.c:697
ch
ch_system_t ch
System data structures.
Definition: chschd.c:42
sysinterval_t
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:119
chThdSleep
void chThdSleep(sysinterval_t time)
Suspends the invoking thread for the specified time.
Definition: chthreads.c:652
chThdSleepS
static void chThdSleepS(sysinterval_t ticks)
Suspends the invoking thread for the specified number of ticks.
Definition: chthreads.h:381
chThdCreate
thread_t * chThdCreate(const thread_descriptor_t *tdp)
Creates a new thread into a static memory area.
Definition: chthreads.c:280
chThdDequeueNextI
void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg)
Dequeues and wakes up one thread from the threads queue object, if any.
Definition: chthreads.c:885
CH_STATE_QUEUED
#define CH_STATE_QUEUED
On a queue.
Definition: chschd.h:67
thread_descriptor_t::name
const char * name
Thread name.
Definition: chthreads.h:61
ch_thread::state
tstate_t state
Current thread state.
Definition: chschd.h:165
chThdResume
void chThdResume(thread_reference_t *trp, msg_t msg)
Wakes up a thread waiting on a thread reference object.
Definition: chthreads.c:835
ch_system::rlist
ready_list_t rlist
Ready list header.
Definition: chschd.h:418
chThdExitS
void chThdExitS(msg_t msg)
Terminates the current thread.
Definition: chthreads.c:501
chThdStart
thread_t * chThdStart(thread_t *tp)
Resumes a thread created with chThdCreateI().
Definition: chthreads.c:379
chThdGetPriorityX
static tprio_t chThdGetPriorityX(void)
Returns the current thread priority.
Definition: chthreads.h:288
chThdRelease
void chThdRelease(thread_t *tp)
Releases a reference to a thread object.
Definition: chthreads.c:427
thread_descriptor_t::prio
tprio_t prio
Thread priority.
Definition: chthreads.h:73
chThdSleepUntil
void chThdSleepUntil(systime_t time)
Suspends the invoking thread until the system time arrives to the specified value.
Definition: chthreads.c:672
chThdGetSelfX
static thread_t * chThdGetSelfX(void)
Returns a pointer to the current thread_t.
Definition: chthreads.h:275
ch_thread::flags
tmode_t flags
Various thread flags.
Definition: chschd.h:169
chThdGetTicksX
static systime_t chThdGetTicksX(thread_t *tp)
Returns the number of ticks consumed by the specified thread.
Definition: chthreads.h:304
chThdExit
void chThdExit(msg_t msg)
Terminates the current thread.
Definition: chthreads.c:477
ch_threads_queue::queue
ch_queue_t queue
Threads queue header.
Definition: chschd.h:125