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