3#ifdef ROO_THREADS_USE_FREERTOS
7#include "freertos/FreeRTOS.h"
8#include "freertos/semphr.h"
9#include "freertos/task.h"
16thread::attributes::attributes()
25 thread::attributes attr;
27 std::unique_ptr<VirtualCallable> start =
nullptr;
29 StaticSemaphore_t join_barrier;
30 StaticSemaphore_t join_mutex;
35void thread::swap(thread& other)
noexcept { std::swap(state_, other.state_); }
37bool thread::joinable() const noexcept {
38 thread_state* state = (thread_state*)state_;
39 return state !=
nullptr;
42thread::~thread() { assert(!joinable()); }
44thread& thread::operator=(thread&& other)
noexcept {
50thread::id thread::get_id() const noexcept {
51 thread_state* state = (thread_state*)state_;
52 if (state_ ==
nullptr) {
53 return thread::id(
nullptr);
55 return thread::id(state->task);
58static void run_thread(
void* arg) {
59 thread_state* p = (thread_state*)arg;
60 std::unique_ptr<VirtualCallable> start = std::move(p->start);
63 if (p->attr.joinable()) {
64 xSemaphoreGive((SemaphoreHandle_t)&p->join_barrier);
65 vTaskSuspend(
nullptr);
72void thread::start(
const attributes& attributes,
73 std::unique_ptr<VirtualCallable> start) {
74 thread_state* state =
new thread_state;
75 assert(state !=
nullptr);
76 state->attr = attributes;
77 state->start = std::move(start);
78 if (state->attr.joinable()) {
79 xSemaphoreCreateMutexStatic(&state->join_mutex);
80 xSemaphoreCreateBinaryStatic(&state->join_barrier);
82 uint32_t stack_size_freertos =
83 (uint32_t)(state->attr.stack_size() /
sizeof(portSTACK_TYPE));
86 if (xTaskCreate(run_thread, state->attr.name(), stack_size_freertos,
87 (
void*)state, state->attr.priority(),
88 &state->task) != pdPASS) {
96 thread_state* state = (thread_state*)state_;
97 assert(state !=
nullptr);
98 assert(state->attr.joinable());
99 if (xSemaphoreTake((SemaphoreHandle_t)&state->join_mutex, 0) != pdPASS) {
102 if (this_thread::get_id() == state->task) {
107 xSemaphoreTake((SemaphoreHandle_t)&state->join_barrier, portMAX_DELAY);
108 xSemaphoreGive((SemaphoreHandle_t)&state->join_barrier);
111 vSemaphoreDelete((SemaphoreHandle_t)&state->join_barrier);
114 xSemaphoreGive((SemaphoreHandle_t)&state->join_mutex);
115 vSemaphoreDelete((SemaphoreHandle_t)&state->join_mutex);
116 vTaskDelete(state->task);
122namespace this_thread {
124thread::id
get_id() noexcept {
return thread::id(xTaskGetCurrentTaskHandle()); }
126void yield() noexcept { vPortYield(); }
128void sleep_for(
const roo_time::Duration& duration) {
134 roo_time::Uptime now = roo_time::Uptime::Now();
135 if (when <= now)
return;
136 roo_time::Duration delta = when - now;
137 vTaskDelay((delta.inMillisRoundedUp() + portTICK_PERIOD_MS - 1) /
#define ROO_THREADS_FREERTOS_DEFAULT_THREAD_PRIORITY
#define ROO_THREADS_FREERTOS_DEFAULT_THREAD_STACK_SIZE
thread::id get_id() noexcept
Returns identifier of the current thread.
void yield() noexcept
Hints the scheduler to run another thread.
void sleep_until(const roo_time::Uptime &when)
Blocks the current thread until the specified time point.
void sleep_for(const roo_time::Duration &duration)
Blocks the current thread for at least the given duration.