#2743 - Implemented ability to core affinity and thread name for pthreads and thus also for std::thread.

This commit is contained in:
Per Malmberg
2018-11-28 20:40:32 +01:00
parent a0468b2bd6
commit 71f57931bd
10 changed files with 242 additions and 11 deletions

View File

@@ -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

View File

@@ -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
*

View File

@@ -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);