diff --git a/components/pthread/port/linux/pthread.c b/components/pthread/port/linux/pthread.c index e5646da4d5a..5f0deb307d8 100644 --- a/components/pthread/port/linux/pthread.c +++ b/components/pthread/port/linux/pthread.c @@ -7,8 +7,25 @@ * pthread port for Linux build */ +#include "sdkconfig.h" #include "esp_pthread.h" +#include "esp_heap_caps.h" + +#include + #include +#include "freertos/FreeRTOS.h" + +static pthread_key_t s_pthread_cfg_key; +static void esp_pthread_cfg_key_destructor(void *value) +{ + free(value); +} + +static int get_default_pthread_core(void) +{ + return CONFIG_PTHREAD_TASK_CORE_DEFAULT == -1 ? tskNO_AFFINITY : CONFIG_PTHREAD_TASK_CORE_DEFAULT; +} /** * @brief Creates a default pthread configuration based @@ -24,8 +41,8 @@ esp_pthread_cfg_t esp_pthread_get_default_config(void) .prio = CONFIG_PTHREAD_TASK_PRIO_DEFAULT, .inherit_cfg = false, .thread_name = NULL, - .pin_to_core = 0, - .stack_alloc_caps = 0, + .pin_to_core = get_default_pthread_core(), + .stack_alloc_caps = MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT, }; return cfg; @@ -33,11 +50,55 @@ esp_pthread_cfg_t esp_pthread_get_default_config(void) esp_err_t esp_pthread_set_cfg(const esp_pthread_cfg_t *cfg) { + if (cfg->stack_size < PTHREAD_STACK_MIN) { + return ESP_ERR_INVALID_ARG; + } + + // 0 is treated as default value, hence change caps to MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL in that case + int heap_caps; + if (cfg->stack_alloc_caps == 0) { + heap_caps = MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL; + } else { + // Check that memory is 8-bit capable + if (!(cfg->stack_alloc_caps & MALLOC_CAP_8BIT)) { + return ESP_ERR_INVALID_ARG; + } + + heap_caps = cfg->stack_alloc_caps; + } + + /* If a value is already set, update that value */ + esp_pthread_cfg_t *p = pthread_getspecific(s_pthread_cfg_key); + if (!p) { + p = malloc(sizeof(esp_pthread_cfg_t)); + if (!p) { + return ESP_ERR_NO_MEM; + } + } + *p = *cfg; + p->stack_alloc_caps = heap_caps; + int __attribute((unused)) res = pthread_setspecific(s_pthread_cfg_key, p); + + assert(res == 0); + return ESP_OK; } esp_err_t esp_pthread_get_cfg(esp_pthread_cfg_t *p) { + esp_pthread_cfg_t *cfg = pthread_getspecific(s_pthread_cfg_key); + if (cfg) { + *p = *cfg; + return ESP_OK; + } memset(p, 0, sizeof(*p)); return ESP_ERR_NOT_FOUND; } + +__attribute__((constructor)) esp_err_t esp_pthread_init(void) +{ + if (pthread_key_create(&s_pthread_cfg_key, esp_pthread_cfg_key_destructor) != 0) { + return ESP_ERR_NO_MEM; + } + return ESP_OK; +} diff --git a/components/pthread/pthread.c b/components/pthread/pthread.c index c0a6f10db67..cf8791f3c3d 100644 --- a/components/pthread/pthread.c +++ b/components/pthread/pthread.c @@ -168,7 +168,7 @@ esp_err_t esp_pthread_set_cfg(const esp_pthread_cfg_t *cfg) pthread_setspecific(s_pthread_cfg_key, p); ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-malloc-leak") // ignore leak of 'p' - return 0; + return ESP_OK; ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-malloc-leak") }