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