ChibiOS 21.11.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 */
52typedef void (*tfunc_t)(void *p);
53
54/**
55 * @brief Type of a thread descriptor.
56 */
57typedef struct {
58 /**
59 * @brief Thread name.
60 */
61 const char *name;
62 /**
63 * @brief Pointer to the working area base.
64 */
66 /**
67 * @brief Pointer to the working area end.
68 */
70 /**
71 * @brief Thread priority.
72 */
74 /**
75 * @brief Thread function pointer.
76 */
78 /**
79 * @brief Thread argument.
80 */
81 void *arg;
82#if (CH_CFG_SMP_MODE != FALSE) || defined(__DOXYGEN__)
83 /**
84 * @brief OS instance affinity or @p NULL for current one.
85 */
87#endif
89
90/*===========================================================================*/
91/* Module macros. */
92/*===========================================================================*/
93
94/**
95 * @name Threads queues
96 * @{
97 */
98/**
99 * @brief Data part of a static threads queue object initializer.
100 * @details This macro should be used when statically initializing a threads
101 * queue that is part of a bigger structure.
102 *
103 * @param[in] name the name of the threads queue variable
104 */
105#define __THREADS_QUEUE_DATA(name) {__CH_QUEUE_DATA(name)}
106
107/**
108 * @brief Static threads queue object initializer.
109 * @details Statically initialized threads queues require no explicit
110 * initialization using @p queue_init().
111 *
112 * @param[in] name the name of the threads queue variable
113 */
114#define THREADS_QUEUE_DECL(name) \
115 threads_queue_t name = __THREADS_QUEUE_DATA(name)
116/** @} */
117
118/**
119 * @name Working Areas
120 * @{
121 */
122/**
123 * @brief Calculates the total Working Area size.
124 *
125 * @param[in] n the stack size to be assigned to the thread
126 * @return The total used memory in bytes.
127 *
128 * @api
129 */
130#define THD_WORKING_AREA_SIZE(n) \
131 MEM_ALIGN_NEXT(sizeof(thread_t) + PORT_WA_SIZE(n), PORT_STACK_ALIGN)
132
133/**
134 * @brief Static working area allocation.
135 * @details This macro is used to allocate a static thread working area
136 * aligned as both position and size.
137 *
138 * @param[in] s the name to be assigned to the stack array
139 * @param[in] n the stack size to be assigned to the thread
140 *
141 * @api
142 */
143#define THD_WORKING_AREA(s, n) PORT_WORKING_AREA(s, n)
144
145/**
146 * @brief Base of a working area casted to the correct type.
147 *
148 * @param[in] s name of the working area
149 */
150#define THD_WORKING_AREA_BASE(s) ((stkalign_t *)(s))
151
152/**
153 * @brief End of a working area casted to the correct type.
154 *
155 * @param[in] s name of the working area
156 */
157#define THD_WORKING_AREA_END(s) (THD_WORKING_AREA_BASE(s) + \
158 (sizeof (s) / sizeof (stkalign_t)))
159/** @} */
160
161/**
162 * @name Threads abstraction macros
163 * @{
164 */
165/**
166 * @brief Thread declaration macro.
167 * @note Thread declarations should be performed using this macro because
168 * the port layer could define optimizations for thread functions.
169 */
170#define THD_FUNCTION(tname, arg) PORT_THD_FUNCTION(tname, arg)
171/** @} */
172
173/**
174 * @name Threads initializers
175 * @{
176 */
177#if (CH_CFG_SMP_MODE != FALSE) || defined(__DOXYGEN__)
178/**
179 * @brief Thread descriptor initializer with no affinity.
180 *
181 * @param[in] name thread name
182 * @param[in] wbase pointer to the working area base
183 * @param[in] wend pointer to the working area end
184 * @param[in] prio thread priority
185 * @param[in] funcp thread function pointer
186 * @param[in] arg thread argument
187 */
188#define THD_DESCRIPTOR(name, wbase, wend, prio, funcp, arg) { \
189 (name), \
190 (wbase), \
191 (wend), \
192 (prio), \
193 (funcp), \
194 (arg), \
195 NULL \
196}
197#else
198#define THD_DESCRIPTOR(name, wbase, wend, prio, funcp, arg) { \
199 (name), \
200 (wbase), \
201 (wend), \
202 (prio), \
203 (funcp), \
204 (arg) \
205}
206#endif
207
208/**
209 * @brief Thread descriptor initializer with no affinity.
210 *
211 * @param[in] name thread name
212 * @param[in] wbase pointer to the working area base
213 * @param[in] wend pointer to the working area end
214 * @param[in] prio thread priority
215 * @param[in] funcp thread function pointer
216 * @param[in] arg thread argument
217 * @param[in] oip instance affinity
218 */
219#define THD_DESCRIPTOR_AFFINITY(name, wbase, wend, prio, funcp, arg, oip) { \
220 (name), \
221 (wbase), \
222 (wend), \
223 (prio), \
224 (funcp), \
225 (arg), \
226 (oip) \
227}
228/** @} */
229
230/**
231 * @name Macro Functions
232 * @{
233 */
234/**
235 * @brief Delays the invoking thread for the specified number of seconds.
236 * @note The specified time is rounded up to a value allowed by the real
237 * system tick clock.
238 * @note The maximum specifiable value is implementation dependent.
239 * @note Use of this macro for large values is not secure because
240 * integer overflows, make sure your value can be correctly
241 * converted.
242 *
243 * @param[in] sec time in seconds, must be different from zero
244 *
245 * @api
246 */
247#define chThdSleepSeconds(sec) chThdSleep(TIME_S2I(sec))
248
249/**
250 * @brief Delays the invoking thread for the specified number of
251 * milliseconds.
252 * @note The specified time is rounded up to a value allowed by the real
253 * system tick clock.
254 * @note The maximum specifiable value is implementation dependent.
255 * @note Use of this macro for large values is not secure because
256 * integer overflows, make sure your value can be correctly
257 * converted.
258 *
259 * @param[in] msec time in milliseconds, must be different from zero
260 *
261 * @api
262 */
263#define chThdSleepMilliseconds(msec) chThdSleep(TIME_MS2I(msec))
264
265/**
266 * @brief Delays the invoking thread for the specified number of
267 * microseconds.
268 * @note The specified time is rounded up to a value allowed by the real
269 * system tick clock.
270 * @note The maximum specifiable value is implementation dependent.
271 * @note Use of this macro for large values is not secure because
272 * integer overflows, make sure your value can be correctly
273 * converted.
274 *
275 * @param[in] usec time in microseconds, must be different from zero
276 *
277 * @api
278 */
279#define chThdSleepMicroseconds(usec) chThdSleep(TIME_US2I(usec))
280/** @} */
281
282/*===========================================================================*/
283/* External declarations. */
284/*===========================================================================*/
285
286#ifdef __cplusplus
287extern "C" {
288#endif
290 thread_t *tp,
291 const char *name,
292 tprio_t prio);
293#if CH_DBG_FILL_THREADS == TRUE
294 void __thd_stackfill(uint8_t *startp, uint8_t *endp);
295#endif
300 thread_t *chThdCreateStatic(void *wsp, size_t size,
301 tprio_t prio, tfunc_t pf, void *arg);
303#if CH_CFG_USE_REGISTRY == TRUE
305 void chThdRelease(thread_t *tp);
306#endif
307 void chThdExit(msg_t msg);
308 void chThdExitS(msg_t msg);
309#if CH_CFG_USE_WAITEXIT == TRUE
311#endif
313 void chThdTerminate(thread_t *tp);
316 void chThdResumeI(thread_reference_t *trp, msg_t msg);
317 void chThdResumeS(thread_reference_t *trp, msg_t msg);
318 void chThdResume(thread_reference_t *trp, msg_t msg);
321 void chThdDequeueAllI(threads_queue_t *tqp, msg_t msg);
322 void chThdSleep(sysinterval_t time);
323 void chThdSleepUntil(systime_t time);
325 void chThdYield(void);
326#ifdef __cplusplus
327}
328#endif
329
330/*===========================================================================*/
331/* Module inline functions. */
332/*===========================================================================*/
333
334/**
335 * @brief Returns a pointer to the current @p thread_t.
336 *
337 * @return A pointer to the current thread.
338 *
339 * @xclass
340 */
341static inline thread_t *chThdGetSelfX(void) {
342
343 return __sch_get_currthread();
344}
345
346/**
347 * @brief Returns the current thread priority.
348 * @note Can be invoked in any context.
349 *
350 * @return The current thread priority.
351 *
352 * @xclass
353 */
354static inline tprio_t chThdGetPriorityX(void) {
355
356 return chThdGetSelfX()->hdr.pqueue.prio;
357}
358
359/**
360 * @brief Returns the number of ticks consumed by the specified thread.
361 * @note This function is only available when the
362 * @p CH_DBG_THREADS_PROFILING configuration option is enabled.
363 *
364 * @param[in] tp pointer to the thread
365 * @return The number of consumed system ticks.
366 *
367 * @xclass
368 */
369#if (CH_DBG_THREADS_PROFILING == TRUE) || defined(__DOXYGEN__)
371
372 return tp->time;
373}
374#endif
375
376#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE) || \
377 defined(__DOXYGEN__)
378/**
379 * @brief Returns the working area base of the specified thread.
380 *
381 * @param[in] tp pointer to the thread
382 * @return The working area base pointer.
383 *
384 * @xclass
385 */
387
388 return tp->wabase;
389}
390#endif /* CH_DBG_ENABLE_STACK_CHECK == TRUE */
391
392/**
393 * @brief Verifies if the specified thread is in the @p CH_STATE_FINAL state.
394 *
395 * @param[in] tp pointer to the thread
396 * @retval true thread terminated.
397 * @retval false thread not terminated.
398 *
399 * @xclass
400 */
401static inline bool chThdTerminatedX(thread_t *tp) {
402
403 return (bool)(tp->state == CH_STATE_FINAL);
404}
405
406/**
407 * @brief Verifies if the current thread has a termination request pending.
408 *
409 * @retval true termination request pending.
410 * @retval false termination request not pending.
411 *
412 * @xclass
413 */
414static inline bool chThdShouldTerminateX(void) {
415
416 return (bool)((chThdGetSelfX()->flags & CH_FLAG_TERMINATE) != (tmode_t)0);
417}
418
419/**
420 * @brief Resumes a thread created with @p chThdCreateI().
421 *
422 * @param[in] tp pointer to the thread
423 * @return The pointer to the @p thread_t structure allocated for
424 * the thread into the working space area.
425 *
426 * @iclass
427 */
428static inline thread_t *chThdStartI(thread_t *tp) {
429
430 chDbgAssert(tp->state == CH_STATE_WTSTART, "wrong state");
431
432 return chSchReadyI(tp);
433}
434
435/**
436 * @brief Suspends the invoking thread for the specified number of ticks.
437 *
438 * @param[in] ticks the delay in system ticks, the special values are
439 * handled as follow:
440 * - @a TIME_INFINITE the thread enters an infinite sleep
441 * state.
442 * - @a TIME_IMMEDIATE this value is not allowed.
443 * .
444 *
445 * @sclass
446 */
447static inline void chThdSleepS(sysinterval_t ticks) {
448
449 chDbgCheck(ticks != TIME_IMMEDIATE);
450
452}
453
454/**
455 * @brief Initializes a threads queue object.
456 *
457 * @param[out] tqp pointer to the threads queue object
458 *
459 * @init
460 */
461static inline void chThdQueueObjectInit(threads_queue_t *tqp) {
462
463 ch_queue_init(&tqp->queue);
464}
465
466/**
467 * @brief Evaluates to @p true if the specified queue is empty.
468 *
469 * @param[out] tqp pointer to the threads queue object
470 * @return The queue status.
471 * @retval false if the queue is not empty.
472 * @retval true if the queue is empty.
473 *
474 * @iclass
475 */
476static inline bool chThdQueueIsEmptyI(threads_queue_t *tqp) {
477
479
480 return ch_queue_isempty(&tqp->queue);
481}
482
483/**
484 * @brief Dequeues and wakes up one thread from the threads queue object.
485 * @details Dequeues one thread from the queue without checking if the queue
486 * is empty.
487 * @pre The queue must contain at least an object.
488 *
489 * @param[in] tqp pointer to the threads queue object
490 * @param[in] msg the message code
491 *
492 * @iclass
493 */
494static inline void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg) {
495 thread_t *tp;
496
497 chDbgAssert(ch_queue_notempty(&tqp->queue), "empty queue");
498
499 tp = threadref(ch_queue_fifo_remove(&tqp->queue));
500
501 chDbgAssert(tp->state == CH_STATE_QUEUED, "invalid state");
502
503 tp->u.rdymsg = msg;
504 (void) chSchReadyI(tp);
505}
506
507#endif /* CHTHREADS_H */
508
509/** @} */
#define chThdQueueIsEmptyI(tqp)
Evaluates to true if the specified queue is empty.
#define chThdQueueObjectInit(tqp)
Initializes a threads queue object.
#define chThdResumeS(trp, msg)
Wakes up a thread waiting on a thread reference object.
#define chThdSleepS(timeout)
Suspends the invoking thread for the specified time.
#define chDbgAssert(c, r)
Condition assertion.
Definition chdebug.h:144
#define chDbgCheck(c)
Function parameters check.
Definition chdebug.h:118
#define chDbgCheckClassI()
Definition chdebug.h:99
static void ch_queue_init(ch_queue_t *qp)
Queue initialization.
Definition chlists.h:222
static bool ch_queue_notempty(const ch_queue_t *qp)
Evaluates to true if the specified queue is not empty.
Definition chlists.h:249
static bool ch_queue_isempty(const ch_queue_t *qp)
Evaluates to true if the specified queue is empty.
Definition chlists.h:236
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:280
#define threadref(p)
Safe cast of a queue pointer to a thread pointer.
Definition chearly.h:206
int32_t msg_t
Definition chearly.h:88
uint32_t tprio_t
Definition chearly.h:87
uint8_t tmode_t
Definition chearly.h:83
struct ch_os_instance os_instance_t
Type of an OS instance structure.
Definition chearly.h:138
thread_t * thread_reference_t
Type of a thread reference.
Definition chobjects.h:138
port_stkalign_t stkalign_t
Definition chearly.h:80
struct ch_thread thread_t
Type of a thread structure.
Definition chearly.h:133
#define CH_STATE_FINAL
Thread terminated.
Definition chschd.h:81
thread_t * chSchReadyI(thread_t *tp)
Inserts a thread in the Ready List placing it behind its peers.
Definition chschd.c:280
#define __sch_get_currthread()
Current thread pointer get macro.
Definition chschd.h:137
#define CH_STATE_QUEUED
On a queue.
Definition chschd.h:67
#define CH_STATE_WTSTART
Just created.
Definition chschd.h:65
#define CH_FLAG_TERMINATE
Termination requested flag.
Definition chschd.h:105
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
#define CH_STATE_SLEEPING
Sleeping.
Definition chschd.h:71
void chThdExitS(msg_t msg)
Terminates the current thread.
Definition chthreads.c:503
msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout)
Enqueues the caller thread on a threads queue object.
Definition chthreads.c:868
static thread_t * chThdGetSelfX(void)
Returns a pointer to the current thread_t.
Definition chthreads.h:341
static systime_t chThdGetTicksX(thread_t *tp)
Returns the number of ticks consumed by the specified thread.
Definition chthreads.h:370
thread_t * chThdCreateSuspended(const thread_descriptor_t *tdp)
Creates a new thread.
Definition chthreads.c:226
void(* tfunc_t)(void *p)
Thread function.
Definition chthreads.h:52
void chThdExit(msg_t msg)
Terminates the current thread.
Definition chthreads.c:479
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:560
void chThdResume(thread_reference_t *trp, msg_t msg)
Wakes up a thread waiting on a thread reference object.
Definition chthreads.c:838
msg_t chThdSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout)
Sends the current thread sleeping and sets a reference variable.
Definition chthreads.c:768
thread_t * __thd_object_init(os_instance_t *oip, thread_t *tp, const char *name, tprio_t prio)
Initializes a thread structure.
Definition chthreads.c:89
thread_t * chThdCreateI(const thread_descriptor_t *tdp)
Creates a new thread.
Definition chthreads.c:264
void chThdResumeI(thread_reference_t *trp, msg_t msg)
Wakes up a thread waiting on a thread reference object.
Definition chthreads.c:793
tprio_t chThdSetPriority(tprio_t newprio)
Changes the running thread priority level then reschedules if necessary.
Definition chthreads.c:600
static void chThdDoDequeueNextI(threads_queue_t *tqp, msg_t msg)
Dequeues and wakes up one thread from the threads queue object.
Definition chthreads.h:494
static thread_t * chThdStartI(thread_t *tp)
Resumes a thread created with chThdCreateI().
Definition chthreads.h:428
void __thd_stackfill(uint8_t *startp, uint8_t *endp)
Stack fill utility.
Definition chthreads.c:140
void chThdSleep(sysinterval_t time)
Suspends the invoking thread for the specified time.
Definition chthreads.c:655
msg_t chThdSuspendS(thread_reference_t *trp)
Sends the current thread sleeping and sets a reference variable.
Definition chthreads.c:737
void chThdRelease(thread_t *tp)
Releases a reference to a thread object.
Definition chthreads.c:429
thread_t * chThdAddRef(thread_t *tp)
Adds a reference to a thread object.
Definition chthreads.c:401
void chThdTerminate(thread_t *tp)
Requests a thread termination.
Definition chthreads.c:636
thread_t * chThdStart(thread_t *tp)
Starts a thread created with chThdCreateSuspended().
Definition chthreads.c:379
void chThdSleepUntil(systime_t time)
Suspends the invoking thread until the system time arrives to the specified value.
Definition chthreads.c:675
static bool chThdTerminatedX(thread_t *tp)
Verifies if the specified thread is in the CH_STATE_FINAL state.
Definition chthreads.h:401
static tprio_t chThdGetPriorityX(void)
Returns the current thread priority.
Definition chthreads.h:354
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:889
thread_t * chThdCreateStatic(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg)
Creates a new thread.
Definition chthreads.c:326
void chThdYield(void)
Yields the time slot.
Definition chthreads.c:720
static stkalign_t * chThdGetWorkingAreaX(thread_t *tp)
Returns the working area base of the specified thread.
Definition chthreads.h:386
static bool chThdShouldTerminateX(void)
Verifies if the current thread has a termination request pending.
Definition chthreads.h:414
thread_t * chThdCreate(const thread_descriptor_t *tdp)
Creates a new thread.
Definition chthreads.c:285
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:700
thread_t * chThdCreateSuspendedI(const thread_descriptor_t *tdp)
Creates a new thread.
Definition chthreads.c:171
void chThdDequeueAllI(threads_queue_t *tqp, msg_t msg)
Dequeues and wakes up all threads from the threads queue object.
Definition chthreads.c:904
uint64_t systime_t
Type of system time.
Definition chtime.h:107
#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
tprio_t prio
Priority of this element.
Definition chlists.h:88
union ch_thread::@065317322233202114332352372014266163076165303275 hdr
Shared list headers.
msg_t rdymsg
Thread wakeup code.
Definition chobjects.h:242
stkalign_t * wabase
Working area base address.
Definition chobjects.h:201
tstate_t state
Current thread state.
Definition chobjects.h:206
volatile systime_t time
Thread consumed time in ticks.
Definition chobjects.h:228
ch_priority_queue_t pqueue
Threads ordered queues element.
Definition chobjects.h:172
union ch_thread::@250330312022121344252011223135034045240103044261 u
State-specific fields.
tmode_t flags
Various thread flags.
Definition chobjects.h:210
Type of a thread descriptor.
Definition chthreads.h:57
stkalign_t * wbase
Pointer to the working area base.
Definition chthreads.h:65
const char * name
Thread name.
Definition chthreads.h:61
stkalign_t * wend
Pointer to the working area end.
Definition chthreads.h:69
void * arg
Thread argument.
Definition chthreads.h:81
tprio_t prio
Thread priority.
Definition chthreads.h:73
tfunc_t funcp
Thread function pointer.
Definition chthreads.h:77
os_instance_t * instance
OS instance affinity or NULL for current one.
Definition chthreads.h:86
Type of a thread queue.
Definition osal.h:238