Skip to content

Commit

Permalink
feat(task): Allow Task::BaseConfig to configure run_on_core and `…
Browse files Browse the repository at this point in the history
…run_on_core_non_blocking` (#332)
  • Loading branch information
finger563 authored Sep 24, 2024
1 parent 1810367 commit 2ba54e5
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 7 deletions.
6 changes: 4 additions & 2 deletions components/task/example/main/task_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ extern "C" void app_main(void) {
// test running a function that returns void on a specific core
auto task_fn = []() -> void { fmt::print("Void Task running on core {}\n", xPortGetCoreID()); };
espp::task::run_on_core(task_fn, 0, 3 * 1024);
fmt::print("Void Function returned\n");
espp::task::run_on_core(task_fn, 1, 3 * 1024);
fmt::print("Void Function returned\n");

Expand All @@ -514,7 +515,8 @@ extern "C" void app_main(void) {
};
auto result0 = espp::task::run_on_core(task_fn2, 0, 3 * 1024);
fmt::print("Bool Function returned {}\n", result0);
auto result1 = espp::task::run_on_core(task_fn2, 1, 3 * 1024);
auto result1 = espp::task::run_on_core(
task_fn2, {.name = "test", .stack_size_bytes = 3 * 1024, .core_id = 1});
fmt::print("Bool Function returned {}\n", result1);

// test running a function that returns esp_err_t on a specific core
Expand Down Expand Up @@ -545,7 +547,7 @@ extern "C" void app_main(void) {
fmt::print("[{0}] Task done!\n", xPortGetCoreID());
};
espp::task::run_on_core_non_blocking(task_fn, 0, 3 * 1024);
espp::task::run_on_core_non_blocking(task_fn, 1);
espp::task::run_on_core_non_blocking(task_fn, {.name = "test", .core_id = 1});
fmt::print("Started tasks on cores 0 and 1\n");

// sleep for a bit to let the tasks run
Expand Down
51 changes: 46 additions & 5 deletions components/task/include/run_on_core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ namespace task {
/// @param core_id The core to run the function on
/// @param stack_size_bytes The stack size to allocate for the function
/// @param priority The priority of the task
/// @param name The name of the task
/// @note This function is only available on ESP32
/// @note If you provide a core_id < 0, the function will run on the current
/// core (same core as the caller)
/// @note If you provide a core_id >= configNUM_CORES, the function will run on
/// the last core
static auto run_on_core(const auto &f, int core_id, size_t stack_size_bytes = 2048,
size_t priority = 5) {
size_t priority = 5, const std::string &name = "run_on_core_task") {
if (core_id < 0 || core_id == xPortGetCoreID()) {
// If no core id specified or we are already executing on the desired core,
// run the function directly
Expand All @@ -41,7 +42,7 @@ static auto run_on_core(const auto &f, int core_id, size_t stack_size_bytes = 20
// the function returns something
decltype(f()) ret_val;
auto f_task = espp::Task::make_unique(espp::Task::Config{
.name = "run_on_core_task",
.name = name,
.callback = [&mutex, &cv, &f, &ret_val](auto &cb_m, auto &cb_cv) -> bool {
// synchronize with the main thread - block here until the main thread
// waits on the condition variable (cv), then run the function
Expand All @@ -62,7 +63,7 @@ static auto run_on_core(const auto &f, int core_id, size_t stack_size_bytes = 20
} else {
// the function returns void
auto f_task = espp::Task::make_unique(espp::Task::Config{
.name = "run_on_core_task",
.name = name,
.callback = [&mutex, &cv, &f](auto &cb_m, auto &cb_cv) -> bool {
// synchronize with the main thread - block here until the main thread
// waits on the condition variable (cv), then run the function
Expand All @@ -83,6 +84,26 @@ static auto run_on_core(const auto &f, int core_id, size_t stack_size_bytes = 20
}
}

/// Run the given function on the specific core, then return the result (if any)
/// @details This function will run the given function on the specified core,
/// then return the result (if any). If the provided core is the same
/// as the current core, the function will run directly. If the
/// provided core is different, the function will be run on the
/// specified core and the result will be returned to the calling
/// thread. Note that this function will block the calling thread until
/// the function has completed, regardless of the core it is run on.
/// @param f The function to run
/// @param task_config The task configuration
/// @note This function is only available on ESP32
/// @note If you provide a core_id < 0, the function will run on the current
/// core (same core as the caller)
/// @note If you provide a core_id >= configNUM_CORES, the function will run on
/// the last core
static auto run_on_core(const auto &f, const espp::Task::BaseConfig &task_config) {
return run_on_core(f, task_config.core_id, task_config.stack_size_bytes, task_config.priority,
task_config.name);
}

/// Run the given function on the specific core without blocking the calling thread
/// @details This function will run the given function on the specified core,
/// without blocking the calling thread / context. A new thread is
Expand All @@ -92,21 +113,23 @@ static auto run_on_core(const auto &f, int core_id, size_t stack_size_bytes = 20
/// @param core_id The core to run the function on
/// @param stack_size_bytes The stack size to allocate for the function
/// @param priority The priority of the task
/// @param name The name of the task
/// @note This function is only available on ESP32
/// @note If you provide a core_id < 0, the thread will not be pinned to any
/// specific core, instead the scheduler will decide which core to run
/// the thread on
/// @note If you provide a core_id >= configNUM_CORES, the function will run on
/// the last core
static void run_on_core_non_blocking(const auto &f, int core_id, size_t stack_size_bytes = 2048,
size_t priority = 5) {
size_t priority = 5,
const std::string &name = "run_on_core_thread") {
// Otherwise run the function on the desired core
if (core_id > configNUM_CORES - 1) {
// If the core id is larger than the number of cores, run on the last core
core_id = configNUM_CORES - 1;
}
auto thread_config = esp_pthread_get_default_config();
thread_config.thread_name = "run_on_core_thread";
thread_config.thread_name = name.c_str();
if (core_id >= 0)
thread_config.pin_to_core = core_id;
thread_config.stack_size = stack_size_bytes;
Expand All @@ -122,6 +145,24 @@ static void run_on_core_non_blocking(const auto &f, int core_id, size_t stack_si
auto thread = std::thread(f);
thread.detach();
}

/// Run the given function on the specific core without blocking the calling thread
/// @details This function will run the given function on the specified core,
/// without blocking the calling thread / context. A new thread is
/// spawned for the function even if the requested core is the same as
/// the core on which the calling thread is running.
/// @param f The function to run
/// @param task_config The task configuration
/// @note This function is only available on ESP32
/// @note If you provide a core_id < 0, the thread will not be pinned to any
/// specific core, instead the scheduler will decide which core to run
/// the thread on
/// @note If you provide a core_id >= configNUM_CORES, the function will run on
/// the last core
static void run_on_core_non_blocking(const auto &f, const espp::Task::BaseConfig &task_config) {
run_on_core_non_blocking(f, task_config.core_id, task_config.stack_size_bytes,
task_config.priority, task_config.name);
}
#endif
} // namespace task
} // namespace espp

0 comments on commit 2ba54e5

Please sign in to comment.