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  LE_THREAD_PRIORITY_NORMAL, ///< Normal, non-real-time priority level. THIS IS THE DEFAULT.
198  LE_THREAD_PRIORITY_RT_1, ///< Real-time priority level 1. The lowest realtime priority
199  /// level.
200  LE_THREAD_PRIORITY_RT_2, ///< Real-time priority level 2.
201  LE_THREAD_PRIORITY_RT_3, ///< Real-time priority level 3.
202  LE_THREAD_PRIORITY_RT_4, ///< Real-time priority level 4.
203  LE_THREAD_PRIORITY_RT_5, ///< Real-time priority level 5.
204  LE_THREAD_PRIORITY_RT_6, ///< Real-time priority level 6.
205  LE_THREAD_PRIORITY_RT_7, ///< Real-time priority level 7.
206  LE_THREAD_PRIORITY_RT_8, ///< Real-time priority level 8.
207  LE_THREAD_PRIORITY_RT_9, ///< Real-time priority level 9.
208  LE_THREAD_PRIORITY_RT_10, ///< Real-time priority level 10.
209  LE_THREAD_PRIORITY_RT_11, ///< Real-time priority level 11.
210  LE_THREAD_PRIORITY_RT_12, ///< Real-time priority level 12.
211  LE_THREAD_PRIORITY_RT_13, ///< Real-time priority level 13.
212  LE_THREAD_PRIORITY_RT_14, ///< Real-time priority level 14.
213  LE_THREAD_PRIORITY_RT_15, ///< Real-time priority level 15.
214  LE_THREAD_PRIORITY_RT_16, ///< Real-time priority level 16.
215  LE_THREAD_PRIORITY_RT_17, ///< Real-time priority level 17.
216  LE_THREAD_PRIORITY_RT_18, ///< Real-time priority level 18.
217  LE_THREAD_PRIORITY_RT_19, ///< Real-time priority level 19.
218  LE_THREAD_PRIORITY_RT_20, ///< Real-time priority level 20.
219  LE_THREAD_PRIORITY_RT_21, ///< Real-time priority level 21.
220  LE_THREAD_PRIORITY_RT_22, ///< Real-time priority level 22.
221  LE_THREAD_PRIORITY_RT_23, ///< Real-time priority level 23.
222  LE_THREAD_PRIORITY_RT_24, ///< Real-time priority level 24.
223  LE_THREAD_PRIORITY_RT_25, ///< Real-time priority level 25.
224  LE_THREAD_PRIORITY_RT_26, ///< Real-time priority level 26.
225  LE_THREAD_PRIORITY_RT_27, ///< Real-time priority level 27.
226  LE_THREAD_PRIORITY_RT_28, ///< Real-time priority level 28.
227  LE_THREAD_PRIORITY_RT_29, ///< Real-time priority level 29.
228  LE_THREAD_PRIORITY_RT_30, ///< Real-time priority level 30.
229  LE_THREAD_PRIORITY_RT_31, ///< Real-time priority level 31.
230  LE_THREAD_PRIORITY_RT_32 ///< Real-time priority level 32.
231 }
233 
234 #define LE_THREAD_PRIORITY_RT_LOWEST LE_THREAD_PRIORITY_RT_1 ///< Lowest real-time priority.
235 #define LE_THREAD_PRIORITY_RT_HIGHEST LE_THREAD_PRIORITY_RT_32 ///< Highest real-time priority.
236 
237 
238 //--------------------------------------------------------------------------------------------------
239 /**
240  * Main functions for threads must look like this:
241  *
242  * @param context [IN] Context value that was passed to le_thread_Create().
243  *
244  * @return Thread result value. If the thread is joinable, then this value can be obtained by
245  * another thread through a call to vt_thread_Join(). Otherwise, the return value is ignored.
246  */
247 //--------------------------------------------------------------------------------------------------
248 typedef void* (* le_thread_MainFunc_t)
249 (
250  void* context ///< See parameter documentation above.
251 );
252 
253 
254 //--------------------------------------------------------------------------------------------------
255 /**
256  * Creates a new Legato thread of execution. After creating the thread, you have the opportunity
257  * to set attributes before it starts. It won't start until le_thread_Start() is called.
258  *
259  * @return A reference to the thread (doesn't return if fails).
260  */
261 //--------------------------------------------------------------------------------------------------
263 (
264  const char* name, ///< [IN] Thread name (will be copied, so can be temporary).
265  le_thread_MainFunc_t mainFunc, ///< [IN] Thread's main function.
266  void* context ///< [IN] Value to pass to mainFunc when it is called.
267 );
268 
269 
270 //--------------------------------------------------------------------------------------------------
271 /**
272  * Sets the priority of a thread.
273  *
274  * @return
275  * - LE_OK if successful.
276  * - LE_OUT_OF_RANGE if the priority level requested is out of range.
277  */
278 //--------------------------------------------------------------------------------------------------
280 (
281  le_thread_Ref_t thread, ///< [IN]
282  le_thread_Priority_t priority ///< [IN]
283 );
284 
285 
286 //--------------------------------------------------------------------------------------------------
287 /**
288  * Sets the stack size of a thread.
289  *
290  * @note It's generally not necessary to set the stack size. Some reasons why you might are:
291  * - to increase it beyond the system's default stack size to prevent overflow
292  * for a thread that makes extremely heavy use of the stack;
293  * - to decrease it to save memory when:
294  * - running in a system that does not support virtual memory
295  * - the thread has very tight real-time constraints that require that the stack
296  * memory be locked into physical memory to avoid page faults.
297  *
298  * @return
299  * - LE_OK if successful.
300  * - LE_OVERFLOW if the stack size requested is too small.
301  * - LE_OUT_OF_RANGE if the stack size requested is too large.
302  */
303 //--------------------------------------------------------------------------------------------------
305 (
306  le_thread_Ref_t thread, ///< [IN]
307  size_t size ///< [IN] Stack size, in bytes. May be rounded up to the
308  /// nearest virtual memory page size.
309 );
310 
311 
312 //--------------------------------------------------------------------------------------------------
313 /**
314  * Makes a thread "joinable", meaning that when it finishes, it will remain in existence until
315  * another thread "joins" with it by calling le_thread_Join(). By default, threads are not
316  * joinable and will be destroyed automatically when they finish.
317  */
318 //--------------------------------------------------------------------------------------------------
320 (
321  le_thread_Ref_t thread ///< [IN]
322 );
323 
324 
325 //--------------------------------------------------------------------------------------------------
326 /**
327  * Starts a new Legato execution thread. After creating the thread, you have the opportunity
328  * to set attributes before it starts. It won't start until le_thread_Start() is called.
329  */
330 //--------------------------------------------------------------------------------------------------
331 void le_thread_Start
332 (
333  le_thread_Ref_t thread ///< [IN]
334 );
335 
336 
337 //--------------------------------------------------------------------------------------------------
338 /**
339  * "Joins" the calling thread with another thread. Blocks the calling thread until the other
340  * thread finishes.
341  *
342  * After a thread has been joined with, its thread reference is no longer valid and must never
343  * be used again.
344  *
345  * The other thread's result value (the value it returned from its main function or passed into
346  * le_thread_Exit()) can be obtained.
347  *
348  * @return
349  * - LE_OK if successful.
350  * - LE_DEADLOCK if a thread tries to join with itself or two threads try to join each other.
351  * - LE_NOT_FOUND if the other thread doesn't exist.
352  * - LE_NOT_POSSIBLE if the other thread can't be joined with.
353  * @deprecated the result code LE_NOT_POSSIBLE is scheduled to be removed before 15.04
354  *
355  * @warning The other thread must be "joinable". See le_thread_SetJoinable();
356  *
357  * @warning It's an error for two or more threads try to join with the same thread.
358  */
359 //--------------------------------------------------------------------------------------------------
361 (
362  le_thread_Ref_t thread, ///< [IN]
363  void** resultValuePtr ///< [OUT] Ptr to where the finished thread's result value
364  /// will be stored. Can be NULL if the result is
365  /// not needed.
366 );
367 
368 
369 //--------------------------------------------------------------------------------------------------
370 /**
371  * Terminates the calling thread.
372  */
373 //--------------------------------------------------------------------------------------------------
374 void le_thread_Exit
375 (
376  void* resultValue ///< [IN] Result value. If this thread is joinable, this result
377  /// can be obtained by another thread calling le_thread_Join()
378  /// on this thread.
379 );
380 
381 
382 //--------------------------------------------------------------------------------------------------
383 /**
384  * Tells another thread to terminate. Returns immediately, but the termination of the
385  * thread happens asynchronously and is not guaranteed to occur when this function returns.
386  *
387  * @return
388  * - LE_OK if successful.
389  * - LE_NOT_FOUND if the thread doesn't exist.
390  */
391 //--------------------------------------------------------------------------------------------------
393 (
394  le_thread_Ref_t threadToCancel ///< [IN] Thread to cancel.
395 );
396 
397 
398 //--------------------------------------------------------------------------------------------------
399 /**
400  * Gets the calling thread's thread reference.
401  *
402  * @return Calling thread's thread reference.
403  */
404 //--------------------------------------------------------------------------------------------------
406 (
407  void
408 );
409 
410 
411 //--------------------------------------------------------------------------------------------------
412 /**
413  * Gets the name of a given thread.
414  */
415 //--------------------------------------------------------------------------------------------------
417 (
418  le_thread_Ref_t threadRef, ///< [IN] Thread to get the name for.
419  char* buffPtr, ///< [OUT] Buffer to store the name of the thread.
420  size_t buffSize ///< [IN] Size of the buffer.
421 );
422 
423 
424 //--------------------------------------------------------------------------------------------------
425 /**
426  * Gets the name of the calling thread.
427  */
428 //--------------------------------------------------------------------------------------------------
429 const char* le_thread_GetMyName
430 (
431  void
432 );
433 
434 
435 //--------------------------------------------------------------------------------------------------
436 /**
437  * Destructor functions for threads must look like this:
438  *
439  * @param context [IN] Context parameter that was passed into le_thread_SetDestructor() when
440  * this destructor was registered.
441  */
442 //--------------------------------------------------------------------------------------------------
443 typedef void (* le_thread_Destructor_t)
444 (
445  void* context ///< [IN] Context parameter that was passed into le_thread_SetDestructor() when
446  /// this destructor was registered.
447 );
448 
449 
450 //--------------------------------------------------------------------------------------------------
451 /**
452  * Reference to a registered destructor function.
453  */
454 //--------------------------------------------------------------------------------------------------
455 typedef struct le_thread_Destructor* le_thread_DestructorRef_t;
456 
457 
458 //--------------------------------------------------------------------------------------------------
459 /**
460  * Registers a destructor function for the calling thread. The destructor will be called by that
461  * thread just before it terminates.
462  *
463  * A thread can register (or remove) its own destructor functions any time.
464  *
465  * @return Reference to the destructor that can be passed to le_thread_RemoveDestructor().
466  *
467  * See @ref threadDestructors for more information on destructors.
468  */
469 //--------------------------------------------------------------------------------------------------
471 (
472  le_thread_Destructor_t destructor, ///< [IN] Function to be called.
473  void* context ///< [IN] Parameter to pass to the destructor.
474 );
475 
476 
477 //--------------------------------------------------------------------------------------------------
478 /**
479  * Registers a destructor function for a child thread. The destructor will be called by the
480  * child thread just before it terminates.
481  *
482  * This can only be done before the child thread is started. After that, only the child thread
483  * can add its own destructors.
484  *
485  * The reason for allowing another thread to register a destructor function is to
486  * avoid a race condition that can cause resource leakage when a parent thread passes dynamically
487  * allocated resources to threads that they create. This is only a problem if the child thread
488  * is expected to release the resources when they are finished with them, and the child thread
489  * may get cancelled at any time.
490  *
491  * For example, a thread @e T1 could allocate an object from a memory pool, create a thread @e T2,
492  * and pass that object to @e T2 for processing and release. @e T2 could register a destructor
493  * function to release the resource whenever it terminates, whether through cancellation or
494  * normal exit. But, if it's possible that @e T2 could get cancelled before it even has a
495  * chance to register a destructor function for itself, the memory pool object could never get
496  * released. So, we allow @e T1 to register a destructor function for @e T2 before starting @e T2.
497  *
498  * See @ref threadDestructors for more information on destructors.
499  */
500 //--------------------------------------------------------------------------------------------------
502 (
503  le_thread_Ref_t thread, ///< [IN] Thread to attach the destructor to.
504  le_thread_Destructor_t destructor, ///< [IN] Function to be called.
505  void* context ///< [IN] Parameter to pass to the destructor.
506 );
507 
508 
509 //--------------------------------------------------------------------------------------------------
510 /**
511  * Removes a destructor function from the calling thread's list of destructors.
512  */
513 //--------------------------------------------------------------------------------------------------
515 (
516  le_thread_DestructorRef_t destructor ///< [in] Reference to the destructor to remove.
517 );
518 
519 
520 //--------------------------------------------------------------------------------------------------
521 /**
522  * Initialize the thread-specific data needed by the Legato framework for the calling thread.
523  *
524  * This is used to turn a non-Legato thread (a thread that was created using a non-Legato API,
525  * such as pthread_create() ) into a Legato thread.
526  *
527  * @note This is not needed if the thread was started using le_thread_Start().
528  **/
529 //--------------------------------------------------------------------------------------------------
531 (
532  const char* name ///< [IN] A name for the thread (will be copied, so can be temporary).
533 );
534 
535 
536 //--------------------------------------------------------------------------------------------------
537 /**
538  * Clean-up the thread-specific data that was initialized using le_thread_InitLegatoThreadData().
539  *
540  * To prevent memory leaks, this must be called by the thread when it dies (unless the whole
541  * process is dying).
542  *
543  * @note This is not needed if the thread was started using le_thread_Start().
544  **/
545 //--------------------------------------------------------------------------------------------------
547 (
548  void
549 );
550 
551 
552 #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:249
Real-time priority level 32.
Definition: le_thread.h:230
Real-time priority level 8.
Definition: le_thread.h:206
Real-time priority level 2.
Definition: le_thread.h:200
Real-time priority level 3.
Definition: le_thread.h:201
Real-time priority level 22.
Definition: le_thread.h:220
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:455
Real-time priority level 10.
Definition: le_thread.h:208
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:223
Real-time priority level 12.
Definition: le_thread.h:210
Real-time priority level 28.
Definition: le_thread.h:226
Real-time priority level 7.
Definition: le_thread.h:205
Real-time priority level 27.
Definition: le_thread.h:225
Real-time priority level 26.
Definition: le_thread.h:224
Real-time priority level 29.
Definition: le_thread.h:227
Real-time priority level 23.
Definition: le_thread.h:221
Real-time priority level 14.
Definition: le_thread.h:212
Real-time priority level 16.
Definition: le_thread.h:214
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:215
Real-time priority level 9.
Definition: le_thread.h:207
le_thread_Priority_t
Definition: le_thread.h:194
Real-time priority level 15.
Definition: le_thread.h:213
Real-time priority level 20.
Definition: le_thread.h:218
Real-time priority level 6.
Definition: le_thread.h:204
void le_thread_CleanupLegatoThreadData(void)
Real-time priority level 24.
Definition: le_thread.h:222
Normal, non-real-time priority level. THIS IS THE DEFAULT.
Definition: le_thread.h:197
void le_thread_InitLegatoThreadData(const char *name)
Real-time priority level 21.
Definition: le_thread.h:219
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:229
void le_thread_AddChildDestructor(le_thread_Ref_t thread, le_thread_Destructor_t destructor, void *context)
Real-time priority level 18.
Definition: le_thread.h:216
Real-time priority level 4.
Definition: le_thread.h:202
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:198
le_thread_Ref_t le_thread_Create(const char *name, le_thread_MainFunc_t mainFunc, void *context)
Real-time priority level 5.
Definition: le_thread.h:203
Real-time priority level 13.
Definition: le_thread.h:211
void(* le_thread_Destructor_t)(void *context)
Definition: le_thread.h:444
Real-time priority level 11.
Definition: le_thread.h:209
Real-time priority level 30.
Definition: le_thread.h:228
Real-time priority level 19.
Definition: le_thread.h:217