le_thread.h

Go to the documentation of this file.
1 /**
2  * @page c_threading Thread Control API
3  *
4  * @ref le_thread.h "API Reference"
5  *
6  * <HR>
7  *
8  * Generally, using single-threaded, event-driven programming (registering callbacks to be called
9  * by an event handling loop running in a single thread) is more efficient than using
10  * multiple threads. With single-threaded, event driven designs:
11  * - there's no CPU time spent switching between threads.
12  * - there's only one copy of thread-specific memory objects, like the procedure call stack.
13  * - there's no need to use thread synchronization mechanisms, like mutexes, to prevent race
14  * conditions between threads.
15  *
16  * Sometimes, this style doesn't fit well with a problem being solved,
17  * so you're forced to implement workarounds that severely complicate
18  * the software design. In these cases, it is far better to take advantage of multi-threading
19  * to simplify the design, even if it means that the program uses more memory or more
20  * CPU cycles. In some cases, the workarounds required to avoid multi-threading will
21  * cost more memory and/or CPU cycles than using multi-threading would.
22  *
23  * But you must <b> be careful </b> with multi-threading. Some of the most tenacious,
24  * intermittent defects known to humankind have resulted from the misuse of multi-threading.
25  * Ensure you know what you are doing.
26  *
27  * @section threadCreating Creating a Thread
28  *
29  * To create a thread, call @c le_thread_Create().
30  *
31  * All threads are @b named for two reasons:
32  * -# To make it possible to address them by name.
33  * -# For diagnostics.
34  *
35  * Threads are created in a suspended state. In this state, attributes like
36  * scheduling priority and stack size can use the appropriate "Set" functions.
37  * All attributes have default values so it is not necessary to set any
38  * attributes (other than the name and main function address, which are passed into
39  * le_thread_Create() ). When all attributes have been set, the thread can be started by calling
40  * le_thread_Start().
41  *
42  * @warning It is assumed that if a thread @e T1 creates another thread @e T2 then @b only thread
43  * @e T1 will set the attributes and start thread @e T2. No other thread should try
44  * to set any attributes of @e T2 or try to start it.
45  *
46  *
47  * @section threadTerminating Terminating a Thread
48  *
49  * Threads can terminate themselves by:
50  * - returning from their main function
51  * - calling le_thread_Exit().
52  *
53  * Threads can also tell other threads to terminate by "canceling" them; done
54  * through a call to @c le_thread_Cancel().
55  *
56  * If a thread terminates itself, and it is "joinable", it can pass a @c void* value to another
57  * thread that "joins" with it. See @ref threadJoining for more information.
58  *
59  * Canceling a thread may not cause the thread to terminate immediately. If it is
60  * in the middle of doing something that can't be interrupted, it will not terminate until it
61  * is finished. See 'man 7 pthreads' for more information on cancellation
62  * and cancellation points.
63  *
64  * To prevent cancellation during a critical section (e.g., when a mutex lock is held),
65  * pthread_setcancelstate() can be called. If a cancellation request is made (by calling
66  * le_thread_Cancel() or <c>pthread_cancel()</c>), it will be blocked and remain in a pending state
67  * until cancellation is unblocked (also using pthread_setcancelstate()), at which time the thread
68  * will be immediately cancelled.
69  *
70  *
71  * @section threadJoining Joining
72  *
73  * Sometimes, you want single execution thread split (fork) into separate
74  * threads of parallel execution and later join back together into one thread later. Forking
75  * is done by creating and starting a thread. Joining is done by a call to le_thread_Join().
76  * le_thread_Join(T) blocks the calling thread until thread T exits.
77  *
78  * For a thread to be joinable, it must have its "joinable" attribute set (using
79  * le_thread_SetJoinable()) prior to being started. Normally, when a thread terminates, it
80  * disappears. But, a joinable thread doesn't disappear until another thread "joins" with it.
81  * This also means that if a thread is joinable, someone must join with it, or its
82  * resources will never get cleaned up (until the process terminates).
83  *
84  * le_thread_Join() fetches the return/exit value of the thread that it joined with.
85  *
86  *
87  * @section threadLocalData Thread-Local Data
88  *
89  * Often, you want data specific to a particular thread. A classic example
90  * of is the ANSI C variable @c errno. If one instance of @c errno was shared by all the
91  * threads in the process, then it would essentially become useless in a multi-threaded program
92  * because it would be impossible to ensure another thread hadn't killed @c errno before
93  * its value could be read. As a result, POSIX has mandated that @c errno be a @a thread-local
94  * variable; each thread has its own unique copy of @c errno.
95  *
96  * If a component needs to make use of other thread-local data, it can do so using the pthread
97  * functions pthread_key_create(), pthread_getspecific(), pthread_setspecific(),
98  * pthread_key_delete(). See the pthread man pages for more details.
99  *
100  *
101  * @section threadSynchronization Thread Synchronization
102  *
103  * Nasty multi-threading defects arise as a result of thread synchronization, or a
104  * lack of synchronization. If threads share data, they @b MUST be synchronized with each other to
105  * avoid destroying that data and incorrect thread behaviour.
106  *
107  * @warning This documentation assumes that the reader is familiar with multi-thread synchronization
108  * techniques and mechanisms.
109  *
110  * The Legato C APIs provide the following thread synchronization mechanisms:
111  * - @ref c_mutex
112  * - @ref c_semaphore
113  * - @ref c_messaging
114  *
115  *
116  * @section threadDestructors Thread Destructors
117  *
118  * When a thread dies, some clean-up action is needed (e.g., a connection
119  * needs to be closed or some objects need to be released). If a thread doesn't always terminate
120  * the same way (e.g., if it might be canceled by another thread or exit in several places due
121  * to error detection code), then a clean-up function (destructor) is probably needed.
122  *
123  * A Legato thread can use @c le_thread_AddDestructor() to register a function to be called
124  * by that thread just before it terminates.
125  *
126  * A parent thread can also call @c le_thread_AddChildDestructor() to register
127  * a destructor for a child thread before it starts the child thread.
128  *
129  * Multiple destructors can be registered for the same thread. They will be called in reverse
130  * order of registration (i.e, the last destructor to be registered will be called first).
131  *
132  * A Legato thread can also use le_thread_RemoveDestructor() to remove its own destructor
133  * function that it no longer wants called in the event of its death. (There is no way to remove
134  * destructors from other threads.)
135  *
136  *
137  * @section threadLegatoizing Using Legato APIs from Non-Legato Threads
138  *
139  * If a thread is started using some other means besides le_thread_Start() (e.g., if
140  * pthread_create() is used directly), then the Legato thread-specific data will not have
141  * been initialized for that thread. Therefore, if that thread tries to call some Legato APIs,
142  * a fatal error message like, "Legato threading API used in non-Legato thread!" may be seen.
143  *
144  * To work around this, a "non-Legato thread" can call le_thread_InitLegatoThreadData() to
145  * initialize the thread-specific data that the Legato framework needs.
146  *
147  * If you have done this for a thread, and that thread will die before the process it is inside
148  * dies, then that thread must call le_thread_CleanupLegatoThreadData() before it exits. Otherwise
149  * the process will leak memory. Furthermore, if the thread will ever be cancelled by another
150  * thread before the process dies, a cancellation clean-up handler can be used to ensure that
151  * the clean-up is done, if the thread's cancellation type is set to "deferred".
152  * See 'man 7 pthreads' for more information on cancellation and cancellation points.
153  *
154  *
155  * <HR>
156  *
157  * Copyright (C) Sierra Wireless Inc. Use of this work is subject to license.
158  */
159 
160 
161 /** @file le_thread.h
162  *
163  * Legato @ref c_threading include file.
164  *
165  * Copyright (C) Sierra Wireless Inc. Use of this work is subject to license.
166  */
167 
168 #ifndef LEGATO_THREAD_INCLUDE_GUARD
169 #define LEGATO_THREAD_INCLUDE_GUARD
170 
171 //--------------------------------------------------------------------------------------------------
172 /**
173  * Reference to a thread of execution.
174  *
175  * @note NULL can be used as an invalid value.
176  */
177 //--------------------------------------------------------------------------------------------------
178 typedef struct le_thread* le_thread_Ref_t;
179 
180 
181 //--------------------------------------------------------------------------------------------------
182 /**
183  * Thread priority levels.
184  *
185  * Real-time priority levels should be avoided unless absolutely necessary for the application.
186  * They are privileged levels and will therefore not be allowed unless the application is executed
187  * by an identity with the appropriate permissions. If a thread running at a real-time priority
188  * level does not block, no other thread at a lower priority level will run, so be careful with
189  * these.
190  *
191  * @note Higher numbers are higher priority.
192  */
193 //--------------------------------------------------------------------------------------------------
194 typedef enum
195 {
196  LE_THREAD_PRIORITY_IDLE = 0, ///< Lowest priority level. Only runs when nothing else to do.
197 
198  LE_THREAD_PRIORITY_LOW, ///< Low, non-realtime priority level.
199  ///< Low, medium, high: intended for normal processes that
200  ///< contend for the CPU. Processes with these priorities don't
201  ///< preempt each other, but their priorities affect how they're
202  ///< inserted into the scheduling queue (high to low).
203  LE_THREAD_PRIORITY_MEDIUM, ///< Medium, non-real-time priority level. THIS IS THE DEFAULT.
204  LE_THREAD_PRIORITY_HIGH, ///< High, non-real-time priority level.
205 
206  LE_THREAD_PRIORITY_RT_1, ///< Real-time priority level 1. The lowest realtime priority
207  /// level.
208  LE_THREAD_PRIORITY_RT_2, ///< Real-time priority level 2.
209  LE_THREAD_PRIORITY_RT_3, ///< Real-time priority level 3.
210  LE_THREAD_PRIORITY_RT_4, ///< Real-time priority level 4.
211  LE_THREAD_PRIORITY_RT_5, ///< Real-time priority level 5.
212  LE_THREAD_PRIORITY_RT_6, ///< Real-time priority level 6.
213  LE_THREAD_PRIORITY_RT_7, ///< Real-time priority level 7.
214  LE_THREAD_PRIORITY_RT_8, ///< Real-time priority level 8.
215  LE_THREAD_PRIORITY_RT_9, ///< Real-time priority level 9.
216  LE_THREAD_PRIORITY_RT_10, ///< Real-time priority level 10.
217  LE_THREAD_PRIORITY_RT_11, ///< Real-time priority level 11.
218  LE_THREAD_PRIORITY_RT_12, ///< Real-time priority level 12.
219  LE_THREAD_PRIORITY_RT_13, ///< Real-time priority level 13.
220  LE_THREAD_PRIORITY_RT_14, ///< Real-time priority level 14.
221  LE_THREAD_PRIORITY_RT_15, ///< Real-time priority level 15.
222  LE_THREAD_PRIORITY_RT_16, ///< Real-time priority level 16.
223  LE_THREAD_PRIORITY_RT_17, ///< Real-time priority level 17.
224  LE_THREAD_PRIORITY_RT_18, ///< Real-time priority level 18.
225  LE_THREAD_PRIORITY_RT_19, ///< Real-time priority level 19.
226  LE_THREAD_PRIORITY_RT_20, ///< Real-time priority level 20.
227  LE_THREAD_PRIORITY_RT_21, ///< Real-time priority level 21.
228  LE_THREAD_PRIORITY_RT_22, ///< Real-time priority level 22.
229  LE_THREAD_PRIORITY_RT_23, ///< Real-time priority level 23.
230  LE_THREAD_PRIORITY_RT_24, ///< Real-time priority level 24.
231  LE_THREAD_PRIORITY_RT_25, ///< Real-time priority level 25.
232  LE_THREAD_PRIORITY_RT_26, ///< Real-time priority level 26.
233  LE_THREAD_PRIORITY_RT_27, ///< Real-time priority level 27.
234  LE_THREAD_PRIORITY_RT_28, ///< Real-time priority level 28.
235  LE_THREAD_PRIORITY_RT_29, ///< Real-time priority level 29.
236  LE_THREAD_PRIORITY_RT_30, ///< Real-time priority level 30.
237  LE_THREAD_PRIORITY_RT_31, ///< Real-time priority level 31.
238  LE_THREAD_PRIORITY_RT_32 ///< Real-time priority level 32.
239 }
241 
242 #define LE_THREAD_PRIORITY_RT_LOWEST LE_THREAD_PRIORITY_RT_1 ///< Lowest real-time priority.
243 #define LE_THREAD_PRIORITY_RT_HIGHEST LE_THREAD_PRIORITY_RT_32 ///< Highest real-time priority.
244 
245 //--------------------------------------------------------------------------------------------------
246 /**
247  * @deprecated
248  *
249  * LE_THREAD_PRIORITY_NORMAL is deprecated, use LE_THREAD_PRIORITY_MEDIUM instead.
250  */
251 //--------------------------------------------------------------------------------------------------
252 #define LE_THREAD_PRIORITY_NORMAL LE_THREAD_PRIORITY_MEDIUM
253 
254 
255 //--------------------------------------------------------------------------------------------------
256 /**
257  * Main functions for threads must look like this:
258  *
259  * @param context [IN] Context value that was passed to le_thread_Create().
260  *
261  * @return Thread result value. If the thread is joinable, then this value can be obtained by
262  * another thread through a call to vt_thread_Join(). Otherwise, the return value is ignored.
263  */
264 //--------------------------------------------------------------------------------------------------
265 typedef void* (* le_thread_MainFunc_t)
266 (
267  void* context ///< See parameter documentation above.
268 );
269 
270 
271 //--------------------------------------------------------------------------------------------------
272 /**
273  * Creates a new Legato thread of execution. After creating the thread, you have the opportunity
274  * to set attributes before it starts. It won't start until le_thread_Start() is called.
275  *
276  * @return A reference to the thread (doesn't return if fails).
277  */
278 //--------------------------------------------------------------------------------------------------
280 (
281  const char* name, ///< [IN] Thread name (will be copied, so can be temporary).
282  le_thread_MainFunc_t mainFunc, ///< [IN] Thread's main function.
283  void* context ///< [IN] Value to pass to mainFunc when it is called.
284 );
285 
286 
287 //--------------------------------------------------------------------------------------------------
288 /**
289  * Sets the priority of a thread.
290  *
291  * @return
292  * - LE_OK if successful.
293  * - LE_OUT_OF_RANGE if the priority level requested is out of range.
294  */
295 //--------------------------------------------------------------------------------------------------
297 (
298  le_thread_Ref_t thread, ///< [IN]
299  le_thread_Priority_t priority ///< [IN]
300 );
301 
302 
303 //--------------------------------------------------------------------------------------------------
304 /**
305  * Sets the stack size of a thread.
306  *
307  * @note It's generally not necessary to set the stack size. Some reasons why you might are:
308  * - to increase it beyond the system's default stack size to prevent overflow
309  * for a thread that makes extremely heavy use of the stack;
310  * - to decrease it to save memory when:
311  * - running in a system that does not support virtual memory
312  * - the thread has very tight real-time constraints that require that the stack
313  * memory be locked into physical memory to avoid page faults.
314  *
315  * @return
316  * - LE_OK if successful.
317  * - LE_OVERFLOW if the stack size requested is too small.
318  * - LE_OUT_OF_RANGE if the stack size requested is too large.
319  */
320 //--------------------------------------------------------------------------------------------------
322 (
323  le_thread_Ref_t thread, ///< [IN]
324  size_t size ///< [IN] Stack size, in bytes. May be rounded up to the
325  /// nearest virtual memory page size.
326 );
327 
328 
329 //--------------------------------------------------------------------------------------------------
330 /**
331  * Makes a thread "joinable", meaning that when it finishes, it will remain in existence until
332  * another thread "joins" with it by calling le_thread_Join(). By default, threads are not
333  * joinable and will be destroyed automatically when they finish.
334  */
335 //--------------------------------------------------------------------------------------------------
337 (
338  le_thread_Ref_t thread ///< [IN]
339 );
340 
341 
342 //--------------------------------------------------------------------------------------------------
343 /**
344  * Starts a new Legato execution thread. After creating the thread, you have the opportunity
345  * to set attributes before it starts. It won't start until le_thread_Start() is called.
346  */
347 //--------------------------------------------------------------------------------------------------
348 void le_thread_Start
349 (
350  le_thread_Ref_t thread ///< [IN]
351 );
352 
353 
354 //--------------------------------------------------------------------------------------------------
355 /**
356  * "Joins" the calling thread with another thread. Blocks the calling thread until the other
357  * thread finishes.
358  *
359  * After a thread has been joined with, its thread reference is no longer valid and must never
360  * be used again.
361  *
362  * The other thread's result value (the value it returned from its main function or passed into
363  * le_thread_Exit()) can be obtained.
364  *
365  * @return
366  * - LE_OK if successful.
367  * - LE_DEADLOCK if a thread tries to join with itself or two threads try to join each other.
368  * - LE_NOT_FOUND if the other thread doesn't exist.
369  * - LE_NOT_POSSIBLE if the other thread can't be joined with.
370  * @deprecated the result code LE_NOT_POSSIBLE is scheduled to be removed before 15.04
371  *
372  * @warning The other thread must be "joinable". See le_thread_SetJoinable();
373  *
374  * @warning It's an error for two or more threads try to join with the same thread.
375  */
376 //--------------------------------------------------------------------------------------------------
378 (
379  le_thread_Ref_t thread, ///< [IN]
380  void** resultValuePtr ///< [OUT] Ptr to where the finished thread's result value
381  /// will be stored. Can be NULL if the result is
382  /// not needed.
383 );
384 
385 
386 //--------------------------------------------------------------------------------------------------
387 /**
388  * Terminates the calling thread.
389  */
390 //--------------------------------------------------------------------------------------------------
391 void le_thread_Exit
392 (
393  void* resultValue ///< [IN] Result value. If this thread is joinable, this result
394  /// can be obtained by another thread calling le_thread_Join()
395  /// on this thread.
396 );
397 
398 
399 //--------------------------------------------------------------------------------------------------
400 /**
401  * Tells another thread to terminate. Returns immediately, but the termination of the
402  * thread happens asynchronously and is not guaranteed to occur when this function returns.
403  *
404  * @return
405  * - LE_OK if successful.
406  * - LE_NOT_FOUND if the thread doesn't exist.
407  */
408 //--------------------------------------------------------------------------------------------------
410 (
411  le_thread_Ref_t threadToCancel ///< [IN] Thread to cancel.
412 );
413 
414 
415 //--------------------------------------------------------------------------------------------------
416 /**
417  * Gets the calling thread's thread reference.
418  *
419  * @return Calling thread's thread reference.
420  */
421 //--------------------------------------------------------------------------------------------------
423 (
424  void
425 );
426 
427 
428 //--------------------------------------------------------------------------------------------------
429 /**
430  * Gets the name of a given thread.
431  */
432 //--------------------------------------------------------------------------------------------------
434 (
435  le_thread_Ref_t threadRef, ///< [IN] Thread to get the name for.
436  char* buffPtr, ///< [OUT] Buffer to store the name of the thread.
437  size_t buffSize ///< [IN] Size of the buffer.
438 );
439 
440 
441 //--------------------------------------------------------------------------------------------------
442 /**
443  * Gets the name of the calling thread.
444  */
445 //--------------------------------------------------------------------------------------------------
446 const char* le_thread_GetMyName
447 (
448  void
449 );
450 
451 
452 //--------------------------------------------------------------------------------------------------
453 /**
454  * Destructor functions for threads must look like this:
455  *
456  * @param context [IN] Context parameter that was passed into le_thread_SetDestructor() when
457  * this destructor was registered.
458  */
459 //--------------------------------------------------------------------------------------------------
460 typedef void (* le_thread_Destructor_t)
461 (
462  void* context ///< [IN] Context parameter that was passed into le_thread_SetDestructor() when
463  /// this destructor was registered.
464 );
465 
466 
467 //--------------------------------------------------------------------------------------------------
468 /**
469  * Reference to a registered destructor function.
470  */
471 //--------------------------------------------------------------------------------------------------
472 typedef struct le_thread_Destructor* le_thread_DestructorRef_t;
473 
474 
475 //--------------------------------------------------------------------------------------------------
476 /**
477  * Registers a destructor function for the calling thread. The destructor will be called by that
478  * thread just before it terminates.
479  *
480  * A thread can register (or remove) its own destructor functions any time.
481  *
482  * @return Reference to the destructor that can be passed to le_thread_RemoveDestructor().
483  *
484  * See @ref threadDestructors for more information on destructors.
485  */
486 //--------------------------------------------------------------------------------------------------
488 (
489  le_thread_Destructor_t destructor, ///< [IN] Function to be called.
490  void* context ///< [IN] Parameter to pass to the destructor.
491 );
492 
493 
494 //--------------------------------------------------------------------------------------------------
495 /**
496  * Registers a destructor function for a child thread. The destructor will be called by the
497  * child thread just before it terminates.
498  *
499  * This can only be done before the child thread is started. After that, only the child thread
500  * can add its own destructors.
501  *
502  * The reason for allowing another thread to register a destructor function is to
503  * avoid a race condition that can cause resource leakage when a parent thread passes dynamically
504  * allocated resources to threads that they create. This is only a problem if the child thread
505  * is expected to release the resources when they are finished with them, and the child thread
506  * may get cancelled at any time.
507  *
508  * For example, a thread @e T1 could allocate an object from a memory pool, create a thread @e T2,
509  * and pass that object to @e T2 for processing and release. @e T2 could register a destructor
510  * function to release the resource whenever it terminates, whether through cancellation or
511  * normal exit. But, if it's possible that @e T2 could get cancelled before it even has a
512  * chance to register a destructor function for itself, the memory pool object could never get
513  * released. So, we allow @e T1 to register a destructor function for @e T2 before starting @e T2.
514  *
515  * See @ref threadDestructors for more information on destructors.
516  */
517 //--------------------------------------------------------------------------------------------------
519 (
520  le_thread_Ref_t thread, ///< [IN] Thread to attach the destructor to.
521  le_thread_Destructor_t destructor, ///< [IN] Function to be called.
522  void* context ///< [IN] Parameter to pass to the destructor.
523 );
524 
525 
526 //--------------------------------------------------------------------------------------------------
527 /**
528  * Removes a destructor function from the calling thread's list of destructors.
529  */
530 //--------------------------------------------------------------------------------------------------
532 (
533  le_thread_DestructorRef_t destructor ///< [in] Reference to the destructor to remove.
534 );
535 
536 
537 //--------------------------------------------------------------------------------------------------
538 /**
539  * Initialize the thread-specific data needed by the Legato framework for the calling thread.
540  *
541  * This is used to turn a non-Legato thread (a thread that was created using a non-Legato API,
542  * such as pthread_create() ) into a Legato thread.
543  *
544  * @note This is not needed if the thread was started using le_thread_Start().
545  **/
546 //--------------------------------------------------------------------------------------------------
548 (
549  const char* name ///< [IN] A name for the thread (will be copied, so can be temporary).
550 );
551 
552 
553 //--------------------------------------------------------------------------------------------------
554 /**
555  * Clean-up the thread-specific data that was initialized using le_thread_InitLegatoThreadData().
556  *
557  * To prevent memory leaks, this must be called by the thread when it dies (unless the whole
558  * process is dying).
559  *
560  * @note This is not needed if the thread was started using le_thread_Start().
561  **/
562 //--------------------------------------------------------------------------------------------------
564 (
565  void
566 );
567 
568 
569 #endif // LEGATO_THREAD_INCLUDE_GUARD
struct le_thread * le_thread_Ref_t
Definition: le_thread.h:178
void *(* le_thread_MainFunc_t)(void *context)
Definition: le_thread.h:266
Real-time priority level 32.
Definition: le_thread.h:238
Real-time priority level 8.
Definition: le_thread.h:214
Real-time priority level 2.
Definition: le_thread.h:208
Real-time priority level 3.
Definition: le_thread.h:209
Real-time priority level 22.
Definition: le_thread.h:228
le_result_t
Definition: le_basics.h:35
void le_thread_RemoveDestructor(le_thread_DestructorRef_t destructor)
le_result_t le_thread_Cancel(le_thread_Ref_t threadToCancel)
struct le_thread_Destructor * le_thread_DestructorRef_t
Definition: le_thread.h:472
Real-time priority level 10.
Definition: le_thread.h:216
le_result_t le_thread_SetStackSize(le_thread_Ref_t thread, size_t size)
le_result_t le_thread_SetPriority(le_thread_Ref_t thread, le_thread_Priority_t priority)
Real-time priority level 25.
Definition: le_thread.h:231
Real-time priority level 12.
Definition: le_thread.h:218
Real-time priority level 28.
Definition: le_thread.h:234
Real-time priority level 7.
Definition: le_thread.h:213
Real-time priority level 27.
Definition: le_thread.h:233
Real-time priority level 26.
Definition: le_thread.h:232
Real-time priority level 29.
Definition: le_thread.h:235
Real-time priority level 23.
Definition: le_thread.h:229
Real-time priority level 14.
Definition: le_thread.h:220
Real-time priority level 16.
Definition: le_thread.h:222
void le_thread_GetName(le_thread_Ref_t threadRef, char *buffPtr, size_t buffSize)
le_result_t le_thread_Join(le_thread_Ref_t thread, void **resultValuePtr)
void le_thread_SetJoinable(le_thread_Ref_t thread)
le_thread_Ref_t le_thread_GetCurrent(void)
Real-time priority level 17.
Definition: le_thread.h:223
Real-time priority level 9.
Definition: le_thread.h:215
le_thread_Priority_t
Definition: le_thread.h:194
Medium, non-real-time priority level. THIS IS THE DEFAULT.
Definition: le_thread.h:203
Real-time priority level 15.
Definition: le_thread.h:221
Real-time priority level 20.
Definition: le_thread.h:226
Real-time priority level 6.
Definition: le_thread.h:212
void le_thread_CleanupLegatoThreadData(void)
Real-time priority level 24.
Definition: le_thread.h:230
void le_thread_InitLegatoThreadData(const char *name)
Real-time priority level 21.
Definition: le_thread.h:227
void le_thread_Exit(void *resultValue)
le_thread_DestructorRef_t le_thread_AddDestructor(le_thread_Destructor_t destructor, void *context)
Real-time priority level 31.
Definition: le_thread.h:237
void le_thread_AddChildDestructor(le_thread_Ref_t thread, le_thread_Destructor_t destructor, void *context)
Definition: le_thread.h:198
Real-time priority level 18.
Definition: le_thread.h:224
Real-time priority level 4.
Definition: le_thread.h:210
const char * le_thread_GetMyName(void)
Lowest priority level. Only runs when nothing else to do.
Definition: le_thread.h:196
void le_thread_Start(le_thread_Ref_t thread)
Definition: le_thread.h:206
le_thread_Ref_t le_thread_Create(const char *name, le_thread_MainFunc_t mainFunc, void *context)
High, non-real-time priority level.
Definition: le_thread.h:204
Real-time priority level 5.
Definition: le_thread.h:211
Real-time priority level 13.
Definition: le_thread.h:219
void(* le_thread_Destructor_t)(void *context)
Definition: le_thread.h:461
Real-time priority level 11.
Definition: le_thread.h:217
Real-time priority level 30.
Definition: le_thread.h:236
Real-time priority level 19.
Definition: le_thread.h:225