mirror of
https://github.com/espressif/esp-idf.git
synced 2025-12-07 09:02:08 +00:00
#2743 - Implemented ability to core affinity and thread name for pthreads and thus also for std::thread.
This commit is contained in:
@@ -19,4 +19,31 @@ config PTHREAD_STACK_MIN
|
||||
help
|
||||
Minimum allowed pthread stack size set in attributes passed to pthread_create
|
||||
|
||||
choice ESP32_PTHREAD_TASK_CORE_DEFAULT
|
||||
bool "Default pthread core affinity"
|
||||
default ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY
|
||||
depends on !FREERTOS_UNICORE
|
||||
help
|
||||
The default core to which pthreads are pinned.
|
||||
|
||||
config ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY
|
||||
bool "No affinity"
|
||||
config ESP32_DEFAULT_PTHREAD_CORE_0
|
||||
bool "Core 0"
|
||||
config ESP32_DEFAULT_PTHREAD_CORE_1
|
||||
bool "Core 1"
|
||||
endchoice
|
||||
|
||||
config ESP32_PTHREAD_TASK_CORE_DEFAULT
|
||||
int
|
||||
default -1 if ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY || FREERTOS_UNICORE
|
||||
default 0 if ESP32_DEFAULT_PTHREAD_CORE_0
|
||||
default 1 if ESP32_DEFAULT_PTHREAD_CORE_1
|
||||
|
||||
config ESP32_PTHREAD_TASK_NAME_DEFAULT
|
||||
string "Default name of pthreads"
|
||||
default "pthread"
|
||||
help
|
||||
The default name of pthreads.
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
#include <freertos/FreeRTOSConfig.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -24,11 +27,22 @@ extern "C" {
|
||||
|
||||
/** pthread configuration structure that influences pthread creation */
|
||||
typedef struct {
|
||||
size_t stack_size; ///< the stack size of the pthread
|
||||
size_t prio; ///< the thread's priority
|
||||
bool inherit_cfg; ///< inherit this configuration further
|
||||
size_t stack_size; ///< The stack size of the pthread
|
||||
size_t prio; ///< The thread's priority
|
||||
bool inherit_cfg; ///< Inherit this configuration further
|
||||
const char* thread_name; ///< The thread name.
|
||||
int pin_to_core; ///< The core id to pin the thread to. Has the same value range as xCoreId argument of xTaskCreatePinnedToCore.
|
||||
} esp_pthread_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief Creates a default pthread configuration based
|
||||
* on the values set via menuconfig.
|
||||
*
|
||||
* @return
|
||||
* A default configuration structure.
|
||||
*/
|
||||
esp_pthread_cfg_t esp_pthread_get_default_config();
|
||||
|
||||
/**
|
||||
* @brief Configure parameters for creating pthread
|
||||
*
|
||||
|
||||
@@ -136,7 +136,6 @@ static void pthread_delete(esp_pthread_t *pthread)
|
||||
free(pthread);
|
||||
}
|
||||
|
||||
|
||||
/* Call this function to configure pthread stacks in Pthreads */
|
||||
esp_err_t esp_pthread_set_cfg(const esp_pthread_cfg_t *cfg)
|
||||
{
|
||||
@@ -168,6 +167,24 @@ esp_err_t esp_pthread_get_cfg(esp_pthread_cfg_t *p)
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
static int get_default_pthread_core()
|
||||
{
|
||||
return CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT == -1 ? tskNO_AFFINITY : CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT;
|
||||
}
|
||||
|
||||
esp_pthread_cfg_t esp_pthread_get_default_config()
|
||||
{
|
||||
esp_pthread_cfg_t cfg = {
|
||||
.stack_size = CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT,
|
||||
.prio = CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT,
|
||||
.inherit_cfg = false,
|
||||
.thread_name = NULL,
|
||||
.pin_to_core = get_default_pthread_core()
|
||||
};
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
static void pthread_task_func(void *arg)
|
||||
{
|
||||
void *rval = NULL;
|
||||
@@ -179,8 +196,13 @@ static void pthread_task_func(void *arg)
|
||||
xTaskNotifyWait(0, 0, NULL, portMAX_DELAY);
|
||||
|
||||
if (task_arg->cfg.inherit_cfg) {
|
||||
/* If inherit option is set, then do a set_cfg() ourselves for future forks */
|
||||
esp_pthread_set_cfg(&task_arg->cfg);
|
||||
/* If inherit option is set, then do a set_cfg() ourselves for future forks,
|
||||
but first set thread_name to NULL to enable inheritance of the name too.
|
||||
(This also to prevents dangling pointers to name of tasks that might
|
||||
possibly have been deleted when we use the configuration).*/
|
||||
esp_pthread_cfg_t *cfg = &task_arg->cfg;
|
||||
cfg->thread_name = NULL;
|
||||
esp_pthread_set_cfg(cfg);
|
||||
}
|
||||
ESP_LOGV(TAG, "%s START %p", __FUNCTION__, task_arg->func);
|
||||
rval = task_arg->func(task_arg->arg);
|
||||
@@ -212,6 +234,8 @@ int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
|
||||
uint32_t stack_size = CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT;
|
||||
BaseType_t prio = CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT;
|
||||
BaseType_t core_id = get_default_pthread_core();
|
||||
const char *task_name = CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT;
|
||||
|
||||
esp_pthread_cfg_t *pthread_cfg = pthread_getspecific(s_pthread_cfg_key);
|
||||
if (pthread_cfg) {
|
||||
@@ -221,6 +245,25 @@ int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
if (pthread_cfg->prio && pthread_cfg->prio < configMAX_PRIORITIES) {
|
||||
prio = pthread_cfg->prio;
|
||||
}
|
||||
|
||||
if (pthread_cfg->inherit_cfg) {
|
||||
if (pthread_cfg->thread_name == NULL) {
|
||||
// Inherit task name from current task.
|
||||
task_name = pcTaskGetTaskName(NULL);
|
||||
} else {
|
||||
// Inheriting, but new task name.
|
||||
task_name = pthread_cfg->thread_name;
|
||||
}
|
||||
} else if (pthread_cfg->thread_name == NULL) {
|
||||
task_name = CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT;
|
||||
} else {
|
||||
task_name = pthread_cfg->thread_name;
|
||||
}
|
||||
|
||||
if (pthread_cfg->pin_to_core >= 0 && pthread_cfg->pin_to_core < portNUM_PROCESSORS) {
|
||||
core_id = pthread_cfg->pin_to_core;
|
||||
}
|
||||
|
||||
task_arg->cfg = *pthread_cfg;
|
||||
}
|
||||
|
||||
@@ -241,9 +284,15 @@ int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
task_arg->func = start_routine;
|
||||
task_arg->arg = arg;
|
||||
pthread->task_arg = task_arg;
|
||||
BaseType_t res = xTaskCreate(&pthread_task_func, "pthread", stack_size,
|
||||
task_arg, prio, &xHandle);
|
||||
if(res != pdPASS) {
|
||||
BaseType_t res = xTaskCreatePinnedToCore(&pthread_task_func,
|
||||
task_name,
|
||||
stack_size,
|
||||
task_arg,
|
||||
prio,
|
||||
&xHandle,
|
||||
core_id);
|
||||
|
||||
if (res != pdPASS) {
|
||||
ESP_LOGE(TAG, "Failed to create task!");
|
||||
free(pthread);
|
||||
free(task_arg);
|
||||
|
||||
Reference in New Issue
Block a user