EtcPal  HEAD (unstable)
ETC Platform Abstraction Layer (EtcPal)
View other versions:
thread (Threading)

Overview

Platform-neutral threads.

#include "etcpal/thread.h"

Provides a platform-neutral threading API with an interface similar to pthread.

void thread_function(void* arg)
{
int val = *(int*)arg;
printf("Hello from a thread! The value is %d.\n", val);
etcpal_thread_sleep(10); // Sleep for 10 milliseconds
}
int arg = 42;
etcpal_error_t result = etcpal_thread_create(&handle, &params, thread_function, &arg);
if (result == kEtcPalErrOk)
{
// The thread is running and prints "Hello from a thread! The value is 42."
// The thread is no longer running.
}
etcpal_error_t
A set of error codes that can be returned by library functions.
Definition: error.h:49
@ kEtcPalErrOk
The call was successful, no error occurred.
Definition: error.h:51
etcpal_error_t etcpal_thread_create(etcpal_thread_t *id, const EtcPalThreadParams *params, void(*thread_fn)(void *), void *thread_arg)
Create a new thread.
PLATFORM_DEFINED etcpal_thread_t
The thread handle.
Definition: thread.dox:35
etcpal_error_t etcpal_thread_join(etcpal_thread_t *id)
Wait for a thread to finish execution.
#define ETCPAL_THREAD_PARAMS_INIT
A default initializer value for an EtcPalThreadParams structure.
Definition: thread.h:191
etcpal_error_t etcpal_thread_sleep(unsigned int sleep_ms)
Provides a platform-neutral sleep.
A set of parameters for an etcpal_thread.
Definition: thread.h:130

On some platforms you can wait a finite time for a thread to exit:

if (etcpal_thread_timed_join(&handle, 1000) == kEtcPalErrOk)
{
// The thread is no longer running.
}
else
{
// If etcpal_thread_timed_join() returns kEtcPalErrTimedOut, the thread failed to stop within
// the timeout given.
}
etcpal_error_t etcpal_thread_timed_join(etcpal_thread_t *id, int timeout_ms)
Wait for a thread to finish execution, giving up after a timeout.

This behavior is platform-dependent:

Platform ETCPAL_THREAD_HAS_TIMED_JOIN
FreeRTOS Yes
Linux No
macOS No
MQX No
Windows Yes
Zephyr Yes

Manipulate the EtcPalThreadParams structure to change parameters about the thread to be created:

// The meaning of these numbers is platform-defined, and they are not honored on all platforms. See the description
// of the EtcPalThreadParams struct for more information.
params.priority = 8;
params.stack_size = 1500;
params.thread_name = "My Thread";
unsigned int priority
The priority of the thread.
Definition: thread.h:132
unsigned int stack_size
The stack size of the thread in bytes.
Definition: thread.h:141
const char * thread_name
A name for the thread, maximum length ETCPAL_THREAD_NAME_MAX_LENGTH.
Definition: thread.h:143

You can also use the etcpal_thread_sleep() function to sleep for a given number of milliseconds from any valid thread context:

etcpal_thread_sleep(200); // Sleep for 200 milliseconds

IMPORTANT NOTE FOR RTOS USERS: The EtcPal threading API does not initialize the scheduler on real-time systems (e.g. it does not call vTaskStartScheduler() on FreeRTOS or _mqx() on MQX). The application writer is responsible for managing the interaction between starting the scheduler and starting EtcPal threads, just like when starting native RTOS tasks.

IMPORTANT NOTES FOR ZEPHYR USERS: Some EtcPal features are dependent on Zephyr configuration see: Targeting Zephyr

Data Structures

struct  EtcPalThreadParams
 A set of parameters for an etcpal_thread. More...
 

Macros

#define ETCPAL_THREAD_SET_DEFAULT_PARAMS(threadparamsptr)
 Set the platform-default values for the EtcPalThreadParams struct. More...
 
#define ETCPAL_THREAD_PARAMS_INIT_VALUES    ETCPAL_THREAD_DEFAULT_PRIORITY, ETCPAL_THREAD_DEFAULT_STACK, ETCPAL_THREAD_DEFAULT_NAME, NULL
 The set of default values for an EtcPalThreadParamsStructure. More...
 
#define ETCPAL_THREAD_PARAMS_INIT
 A default initializer value for an EtcPalThreadParams structure. More...
 
#define ETCPAL_THREAD_DEFAULT_PRIORITY
 The platform-specific default priority for an etcpal_thread. More...
 
#define ETCPAL_THREAD_DEFAULT_STACK
 The plaform-specific default stack size for an etcpal_thread. More...
 
#define ETCPAL_THREAD_DEFAULT_NAME
 The default name for an etcpal_thread.
 
#define ETCPAL_THREAD_NAME_MAX_LENGTH
 The maximum length of an etcpal_thread name C-string.
 
#define ETCPAL_THREAD_OS_HANDLE_INVALID   /* platform-defined */
 An invalid value for the native OS thread handle type. More...
 
#define ETCPAL_THREAD_HAS_TIMED_JOIN   /* platform-defined */
 Whether etcpal_thread_timed_join() is meaningful on this platform. More...
 

Typedefs

typedef struct EtcPalThreadParams EtcPalThreadParams
 A set of parameters for an etcpal_thread. More...
 
typedef PLATFORM_DEFINED etcpal_thread_t
 The thread handle. More...
 
typedef PLATFORM_DEFINED etcpal_thread_os_handle_t
 The native OS handle type for threads on this platform. More...
 

Functions

etcpal_error_t etcpal_thread_create (etcpal_thread_t *id, const EtcPalThreadParams *params, void(*thread_fn)(void *), void *thread_arg)
 Create a new thread. More...
 
etcpal_error_t etcpal_thread_sleep (unsigned int sleep_ms)
 Provides a platform-neutral sleep. More...
 
etcpal_error_t etcpal_thread_join (etcpal_thread_t *id)
 Wait for a thread to finish execution. More...
 
etcpal_error_t etcpal_thread_timed_join (etcpal_thread_t *id, int timeout_ms)
 Wait for a thread to finish execution, giving up after a timeout. More...
 
etcpal_error_t etcpal_thread_terminate (etcpal_thread_t *id)
 Forcefully kill a thread. More...
 
etcpal_thread_os_handle_t etcpal_thread_get_os_handle (etcpal_thread_t *id)
 Get the native OS handle of an EtcPal thread. More...
 
etcpal_thread_os_handle_t etcpal_thread_get_current_os_handle (void)
 Get the native OS handle of the currently executing thread. More...
 

Macro Definition Documentation

◆ ETCPAL_THREAD_DEFAULT_PRIORITY

#define ETCPAL_THREAD_DEFAULT_PRIORITY

The platform-specific default priority for an etcpal_thread.

Note that thread priority is not valid on all platforms.

◆ ETCPAL_THREAD_DEFAULT_STACK

#define ETCPAL_THREAD_DEFAULT_STACK

The plaform-specific default stack size for an etcpal_thread.

Note that thread stack size is not valid on all platforms.

◆ ETCPAL_THREAD_HAS_TIMED_JOIN

#define ETCPAL_THREAD_HAS_TIMED_JOIN   /* platform-defined */

Whether etcpal_thread_timed_join() is meaningful on this platform.

If defined to 0, etcpal_thread_timed_join() executes the equivalent of etcpal_thread_join(), and the timeout_ms argument is ignored.

◆ ETCPAL_THREAD_OS_HANDLE_INVALID

#define ETCPAL_THREAD_OS_HANDLE_INVALID   /* platform-defined */

An invalid value for the native OS thread handle type.

Warning
On POSIX platforms (currently Linux and macOS), there is no defined value for an invalid pthread_t. This is defined to (pthread_t)-1 as a heuristic.

◆ ETCPAL_THREAD_PARAMS_INIT

#define ETCPAL_THREAD_PARAMS_INIT
Value:
{ \
ETCPAL_THREAD_PARAMS_INIT_VALUES \
}

A default initializer value for an EtcPalThreadParams structure.

Usage:

◆ ETCPAL_THREAD_PARAMS_INIT_VALUES

#define ETCPAL_THREAD_PARAMS_INIT_VALUES    ETCPAL_THREAD_DEFAULT_PRIORITY, ETCPAL_THREAD_DEFAULT_STACK, ETCPAL_THREAD_DEFAULT_NAME, NULL

The set of default values for an EtcPalThreadParamsStructure.

Suitable for using in a bracket initializer, e.g.:

#define ETCPAL_THREAD_PARAMS_INIT_VALUES
The set of default values for an EtcPalThreadParamsStructure.
Definition: thread.h:180

◆ ETCPAL_THREAD_SET_DEFAULT_PARAMS

#define ETCPAL_THREAD_SET_DEFAULT_PARAMS (   threadparamsptr)
Value:
do \
{ \
(threadparamsptr)->priority = ETCPAL_THREAD_DEFAULT_PRIORITY; \
(threadparamsptr)->stack_size = ETCPAL_THREAD_DEFAULT_STACK; \
(threadparamsptr)->thread_name = ETCPAL_THREAD_DEFAULT_NAME; \
(threadparamsptr)->platform_data = NULL; \
} while (0)
#define ETCPAL_THREAD_DEFAULT_PRIORITY
The platform-specific default priority for an etcpal_thread.
Definition: thread.dox:15
#define ETCPAL_THREAD_DEFAULT_NAME
The default name for an etcpal_thread.
Definition: thread.dox:25
#define ETCPAL_THREAD_DEFAULT_STACK
The plaform-specific default stack size for an etcpal_thread.
Definition: thread.dox:22

Set the platform-default values for the EtcPalThreadParams struct.

Typedef Documentation

◆ etcpal_thread_os_handle_t

typedef PLATFORM_DEFINED etcpal_thread_os_handle_t

The native OS handle type for threads on this platform.

This is a scalar type on all platforms for which EtcPal is ported.

◆ etcpal_thread_t

typedef PLATFORM_DEFINED etcpal_thread_t

The thread handle.

Depending on the platform, this could be a scalar type or a struct.

◆ EtcPalThreadParams

A set of parameters for an etcpal_thread.

The members of this structure are not all honored on all platforms. Here is a breakdown:

Platform Priority Honored Stack Size Honored Thread Name Honored Platform Data Available
FreeRTOS Yes Yes Yes No
Linux No Yes Yes No
macOS No Yes Yes No
MQX Yes Yes Yes Yes, EtcPalThreadParamsMqx
Windows Yes Yes Yes No
Zephyr Yes Yes Yes No

Function Documentation

◆ etcpal_thread_create()

etcpal_error_t etcpal_thread_create ( etcpal_thread_t id,
const EtcPalThreadParams params,
void(*)(void *)  thread_fn,
void *  thread_arg 
)

Create a new thread.

If your application has exit/shutdown behavior (i.e. it is a non-embedded application), it's good practice to always pair this with a call to etcpal_thread_join() on exit. On some platforms, extra signaling resources are allocated when the thread is created that are not deallocated unless etcpal_thread_join() is called.

Parameters
[out]idIdentifier for the thread that was created.
[in]paramsThread parameters for the thread to create
[in]thread_fnPointer to function that should be called from the new thread. This function takes one void* argument and returns void.
[in]thread_argArgument to the function called from the new thread.
Returns
kEtcPalErrOk: The thread was created.
kEtcPalErrInvalid: Invalid argument.
Other codes translated from system error codes are possible.

◆ etcpal_thread_get_current_os_handle()

etcpal_thread_os_handle_t etcpal_thread_get_current_os_handle ( void  )

Get the native OS handle of the currently executing thread.

This cannot be converted back to an etcpal_thread_t, but it can be used as a thread identifier for non-EtcPal purposes.

◆ etcpal_thread_get_os_handle()

etcpal_thread_os_handle_t etcpal_thread_get_os_handle ( etcpal_thread_t id)

Get the native OS handle of an EtcPal thread.

Parameters
[in]idIdentifier for the thread for which to get the OS handle.
Returns
The OS handle, or ETCPAL_THREAD_OS_HANDLE_INVALID if an invalid argument was given.

◆ etcpal_thread_join()

etcpal_error_t etcpal_thread_join ( etcpal_thread_t id)

Wait for a thread to finish execution.

Blocks until the thread has exited.

Parameters
[in]idIdentifier for the thread to stop.
Returns
kEtcPalErrOk: The thread was stopped.
kEtcPalErrInvalid: id does not represent a joinable thread.
Other codes translated from system error codes are possible.

◆ etcpal_thread_sleep()

etcpal_error_t etcpal_thread_sleep ( unsigned int  sleep_ms)

Provides a platform-neutral sleep.

Parameters
[in]sleep_msHow long to sleep, in milliseconds.
Returns
kEtcPalErrOk: The sleep completed.
kEtcPalErrSys: The system call may have been interrupted and awoke early.

◆ etcpal_thread_terminate()

etcpal_error_t etcpal_thread_terminate ( etcpal_thread_t id)

Forcefully kill a thread.

Be careful when using this function. Depending on the state of a thread when it is terminated, shared resources or memory could not be freed, resulting in memory leaks or deadlocks.

Parameters
[in]idIdentifier for the thread to terminate.
Returns
kEtcPalErrOk: The thread was terminated.
kEtcPalErrInvalid: id does not represent a joinable thread.
Other codes translated from system error codes are possible.

◆ etcpal_thread_timed_join()

etcpal_error_t etcpal_thread_timed_join ( etcpal_thread_t id,
int  timeout_ms 
)

Wait for a thread to finish execution, giving up after a timeout.

This function is not honored on all platforms. The value of ETCPAL_THREAD_HAS_TIMED_JOIN can be used to determine whether this function is honored on the current platform. If it is defined to 0, this function executes the equivalent of etcpal_thread_join(), and the timeout_ms argument is ignored.

Parameters
[in]idIdentifier for the thread to stop.
[in]timeout_msMaximum amount of time to wait for the thread, in milliseconds. If ETCPAL_WAIT_FOREVER is given, the result is the same as if etcpal_thread_join() was called.
Returns
kEtcPalErrOk: The thread was stopped.
kEtcPalErrInvalid: id does not represent a joinable thread.
kEtcPalErrTimedOut: Timed out waiting for the thread to stop.
Other codes translated from system error codes are possible.