#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

@@ -0,0 +1,6 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(cpp_pthread)

View File

@@ -0,0 +1,9 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := cpp_pthread
include $(IDF_PATH)/make/project.mk

View File

@@ -0,0 +1,5 @@
# pthread examples
This example shows how to use the pthread API to create std::threads with different stack sizes, names, priorities and pinned to certain cores.
This example is in C++, contrary to the the normal standard of pure C.

View File

@@ -0,0 +1,4 @@
set(COMPONENT_SRCS "cpp_pthread.cpp")
set(COMPONENT_ADD_INCLUDEDIRS ".")
register_component()

View File

@@ -0,0 +1,3 @@
#
# Main Makefile. This is basically the same as a component makefile.
#

View File

@@ -0,0 +1,112 @@
/* pthread/std::thread example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <iostream>
#include <thread>
#include <chrono>
#include <memory>
#include <string>
#include <sstream>
#include <esp_pthread.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <esp_log.h>
using namespace std::chrono;
const auto sleep_time = seconds
{
5
};
void print_thread_info(const char *extra = nullptr)
{
std::stringstream ss;
if (extra) {
ss << extra;
}
ss << "Core id: " << xPortGetCoreID()
<< ", prio: " << uxTaskPriorityGet(nullptr)
<< ", minimum free stack: " << uxTaskGetStackHighWaterMark(nullptr) << " bytes.";
ESP_LOGI(pcTaskGetTaskName(nullptr), "%s", ss.str().c_str());
}
void thread_func_inherited()
{
while (true) {
print_thread_info("This is the INHERITING thread with the same parameters as our parent, including name. ");
std::this_thread::sleep_for(sleep_time);
}
}
void spawn_another_thread()
{
// Create a new thread, it will inherit our configuration
std::thread inherits(thread_func_inherited);
while (true) {
print_thread_info();
std::this_thread::sleep_for(sleep_time);
}
}
void thread_func_any_core()
{
while (true) {
print_thread_info("This thread (with the default name) may run on any core.");
std::this_thread::sleep_for(sleep_time);
}
}
void thread_func()
{
while (true) {
print_thread_info();
std::this_thread::sleep_for(sleep_time);
}
}
esp_pthread_cfg_t create_config(const char *name, int core_id, int stack, int prio)
{
auto cfg = esp_pthread_get_default_config();
cfg.thread_name = name;
cfg.pin_to_core = core_id;
cfg.stack_size = stack;
cfg.prio = prio;
return cfg;
}
extern "C" void app_main()
{
// Create a thread using deafult values that can run on any core
auto cfg = esp_pthread_get_default_config();
esp_pthread_set_cfg(&cfg);
std::thread any_core(thread_func_any_core);
// Create a thread on core 0 that spawns another thread, they will both have the same name etc.
cfg = create_config("Thread 1", 0, 3 * 1024, 5);
cfg.inherit_cfg = true;
esp_pthread_set_cfg(&cfg);
std::thread thread_1(spawn_another_thread);
// Create a thread on core 1.
cfg = create_config("Thread 2", 1, 3 * 1024, 5);
esp_pthread_set_cfg(&cfg);
std::thread thread_2(thread_func);
// Let the main task do something too
while (true) {
std::stringstream ss;
ss << "core id: " << xPortGetCoreID()
<< ", prio: " << uxTaskPriorityGet(nullptr)
<< ", minimum free stack: " << uxTaskGetStackHighWaterMark(nullptr) << " bytes.";
ESP_LOGI(pcTaskGetTaskName(nullptr), "%s", ss.str().c_str());
std::this_thread::sleep_for(sleep_time);
}
}