roo_threads
API Documentation for roo_threads
Loading...
Searching...
No Matches
thread.h
Go to the documentation of this file.
1#pragma once
2
4
5#ifdef ROO_THREADS_USE_FREERTOS
6
8#include "roo_time.h"
9
10#define ROO_THREADS_ATTRIBUTES_SUPPORT_PRIORITY 1
11#define ROO_THREADS_ATTRIBUTES_SUPPORT_NAME 1
12#define ROO_THREADS_ATTRIBUTES_SUPPORT_STACK_SIZE 1
13
14namespace roo_threads {
15
16/// @brief Backend namespace using FreeRTOS threading primitives.
17namespace freertos {
18
19/// @ingroup roo_threads_api_thread
20/// @brief FreeRTOS backend implementation of `roo::thread`.
21/// @copydoc roo_threads::doc::thread
22class thread {
23 public:
24 /// @copydoc roo_threads::doc::thread::id
25 class id;
26
27 /// @brief FreeRTOS-specific thread attributes.
28 /// @copydoc roo_threads::doc::thread::attributes
29 class attributes {
30 public:
31 /// @copydoc roo_threads::doc::thread::attributes::attributes
32 attributes();
33
34 /// @copydoc roo_threads::doc::thread::attributes::stack_size
35 uint32_t stack_size() const { return stack_size_; }
36 /// @copydoc roo_threads::doc::thread::attributes::priority
37 uint16_t priority() const { return priority_; }
38 /// @copydoc roo_threads::doc::thread::attributes::joinable
39 bool joinable() const { return joinable_; }
40 /// @copydoc roo_threads::doc::thread::attributes::name
41 const char* name() const { return name_; }
42
43 /// @copydoc roo_threads::doc::thread::attributes::set_stack_size
44 void set_stack_size(uint32_t stack_size) { stack_size_ = stack_size; }
45
46 /// @copydoc roo_threads::doc::thread::attributes::set_priority
47 void set_priority(uint16_t priority) { priority_ = priority; }
48
49 /// @copydoc roo_threads::doc::thread::attributes::set_name
50 void set_name(const char* name) { name_ = name; }
51
52 private:
53 friend class thread;
54
55 uint32_t stack_size_;
56 uint16_t priority_;
57 bool joinable_;
58 const char* name_;
59 };
60
61 /// @copydoc roo_threads::doc::thread::thread() noexcept
62 thread() noexcept : state_(nullptr) {}
63
64 thread(const thread&) = delete;
65
66 /// @copydoc roo_threads::doc::thread::thread(thread&&)
67 thread(thread&& other) noexcept : thread() { swap(other); }
68
69 /// @copydoc roo_threads::doc::thread::thread(Callable&&,Args&&...)
70 template <
71 typename Callable, typename... Args,
72 typename = typename std::enable_if<!std::is_same<
73 std::remove_reference_t<Callable>, thread::attributes>::value>::type,
74 typename =
75 typename std::enable_if<!std::is_same<Callable, thread>::value>::type>
76 explicit thread(Callable&& callable, Args&&... args) {
77 static_assert(std::is_invocable<typename std::decay<Callable>::type,
78 typename std::decay<Args>::type...>::value,
79 "roo::thread argument must be invocable");
80 start(attributes(),
81 MakeDynamicCallableWithArgs(std::forward<Callable>(callable),
82 std::forward<Args>(args)...));
83 }
84
85 /// @copydoc roo_threads::doc::thread::thread(const
86 /// attributes&,Callable&&,Args&&...)
87 template <typename Callable, typename... Args,
88 typename = typename std::enable_if<
89 !std::is_same<Callable, thread>::value>::type>
90 explicit thread(const attributes& attrs, Callable&& callable,
91 Args&&... args) {
92 static_assert(std::is_invocable<typename std::decay<Callable>::type,
93 typename std::decay<Args>::type...>::value,
94 "roo::thread argument must be invocable");
95
96 start(attrs, MakeDynamicCallableWithArgs(std::forward<Callable>(callable),
97 std::forward<Args>(args)...));
98 }
99
100 /// @copydoc roo_threads::doc::thread::~thread
101 ~thread();
102
103 thread& operator=(const thread&) = delete;
104
105 /// @copydoc roo_threads::doc::thread::operator=(thread&&)
106 thread& operator=(thread&& other) noexcept;
107
108 /// @copydoc roo_threads::doc::thread::swap
109 void swap(thread& other) noexcept;
110
111 /// @copydoc roo_threads::doc::thread::joinable
112 bool joinable() const noexcept;
113
114 /// @copydoc roo_threads::doc::thread::join
115 void join();
116
117 /// @copydoc roo_threads::doc::thread::detach
118 void detach();
119
120 /// @copydoc roo_threads::doc::thread::get_id
121 thread::id get_id() const noexcept;
122
123 private:
124 void start(const attributes& attributes, std::unique_ptr<VirtualCallable>);
125
126 void* state_;
127};
128
129namespace this_thread {
130
131/// @ingroup roo_threads_api_thread
132/// @copydoc roo_threads::doc::this_thread::get_id
133thread::id get_id() noexcept;
134
135/// @ingroup roo_threads_api_thread
136/// @copydoc roo_threads::doc::this_thread::yield
137void yield() noexcept;
138
139/// @ingroup roo_threads_api_thread
140/// @copydoc roo_threads::doc::this_thread::sleep_for
141/// @note FreeRTOS delay resolution is scheduler-tick based.
142void sleep_for(const roo_time::Duration& duration);
143
144/// @ingroup roo_threads_api_thread
145/// @copydoc roo_threads::doc::this_thread::sleep_until
146/// @note FreeRTOS delay resolution is scheduler-tick based.
147void sleep_until(const roo_time::Uptime& when);
148
149} // namespace this_thread
150
151class thread::id {
152 public:
153 /// @copydoc roo_threads::doc::thread::id::id
154 id() : id_(nullptr) {}
155 /// @copydoc roo_threads::doc::thread::id::operator==
156 bool operator==(const id& other) const { return id_ == other.id_; }
157 /// @copydoc roo_threads::doc::thread::id::operator!=
158 bool operator!=(const id& other) const { return id_ != other.id_; }
159 /// @copydoc roo_threads::doc::thread::id::operator<
160 bool operator<(const id& other) const { return id_ < other.id_; }
161 /// @copydoc roo_threads::doc::thread::id::operator<=
162 bool operator<=(const id& other) const { return id_ <= other.id_; }
163 /// @copydoc roo_threads::doc::thread::id::operator>
164 bool operator>(const id& other) const { return id_ > other.id_; }
165 /// @copydoc roo_threads::doc::thread::id::operator>=
166 bool operator>=(const id& other) const { return id_ >= other.id_; }
167
168 private:
169 id(void* id) : id_(id) {}
170
171 friend class thread;
172 friend id this_thread::get_id() noexcept;
173
174 void* id_;
175};
176
177} // namespace freertos
178} // namespace roo_threads
179
180#endif // ROO_THREADS_USE_FREERTOS
thread::id get_id() noexcept
Returns identifier of the current thread.