RTEMS 6.1-rc1
thread.hpp
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-2-Clause */
2
17/*
18 * Copyright (C) 2020 Chris Johns (http://contemporary.software)
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
22 * are met:
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 */
41
42#if !defined(RTEMS_THREAD_HPP)
43#define RTEMS_THREAD_HPP
44
45#include <functional>
46#include <iostream>
47#include <string>
48#include <thread>
49#include <utility>
50
51namespace rtems
52{
53 namespace thread
54 {
59 {
60 public:
69 };
70
79 };
80
86 attributes();
87
88 /*
89 * Copy construct the thread attributes.
90 *
91 * @param attr The attributes to copy.
92 */
93 attributes(const attributes& attr);
94
101 void set_name(const std::string& name);
102
109 void set_name(const char* name);
110
116 const std::string& get_name() const;
117
123 void set_priority(int priority);
124
130 int get_priority() const;
131
138 void set_stack_size(size_t size);
139
145 size_t get_stack_size() const;
146
152 void set_scheduler(const std::string& scheduler);
153
157 void set_scheduler(const char* scheduler);
158
162 const std::string& get_scheduler();
163
170
178
183
190 void commit();
191
200 void update();
201
205 attributes& operator=(const attributes& attr);
206
211 bool operator==(const attributes& attr) const;
212
213 private:
214 std::string name;
215 int priority;
216 size_t stack_size;
217 std::string scheduler;
218 sched_attr attr;
219 sched_policy policy;
220 /* affinity, cpu set size is? */
221 };
222
223 template <class T>
224 inline typename std::decay<T>::type
225 decay_copy(T&& t) {
226 return std::forward<T>(t);
227 }
228
250 class thread
251 {
252 friend void* thread_generic_entry(void* arg);
253
258 struct state_base
259 {
260 virtual ~state_base();
261 virtual const attributes get_attributes() = 0;
262 virtual void run() = 0;
263 };
264
269 using state_ptr = std::unique_ptr<state_base>;
270
271 public:
272
277 template <typename A, class DecayA = typename std::decay<A>::type>
278 using enable_if_attributes = typename std::enable_if
279 <std::is_same<DecayA, attributes>::value>::type;
280
285 class id {
286 public:
287 id() noexcept : id_(0) { }
288 explicit id(pthread_t id_) : id_(id_) { }
289 private:
290 pthread_t id_;
291
292 friend class thread;
293 friend bool operator==(thread::id l, thread::id r) noexcept;
294
295 template<class CharT, class Traits>
296 friend std::basic_ostream<CharT, Traits>&
297 operator<<(std::basic_ostream<CharT, Traits>& out, thread::id id_);
298 };
299
303 thread() noexcept = default;
304
310 template<typename F, typename... Args>
311 explicit thread(F&& func, Args&&... args);
312
317 template <typename A, typename F, typename ...Args,
318 class = enable_if_attributes<A>>
319 explicit thread(A&& attr, F&& func, Args&&... args)
320 : id_(0) {
321 start_thread(
322 make_state(attr,
323 make_invoker(decay_copy(std::forward<F>(func)),
324 decay_copy(std::forward<Args>(args))...))
325 );
326 }
327
331 thread& operator=(thread&& thread_);
332
333 void swap(thread& thread_) noexcept;
334
335 bool joinable() const noexcept;
336
337 void join();
338
339 void detach();
340
341 /*
342 * Constrain use. These are not available.
343 */
344 thread(thread&) = delete;
345 thread(const thread&) = delete;
346 thread(const thread&&) = delete;
347 thread& operator=(const thread&) = delete;
348
349 std::thread::id get_id() const noexcept;
350
351 private:
352
353 id id_;
354
360 template<typename Parms>
361 struct invoker {
362 Parms p;
363
364 template<size_t Index>
365 static std::__tuple_element_t<Index, Parms>&& declval();
366
367 template<size_t... Ind>
368 auto invoke(std::_Index_tuple<Ind...>)
369 noexcept(noexcept(std::invoke(declval<Ind>()...)))
370 -> decltype(std::invoke(declval<Ind>()...)) {
371 return std::invoke(std::get<Ind>(std::move(p))...);
372 }
373
374 using indices =
375 typename std::_Build_index_tuple<std::tuple_size<Parms>::value>::__type;
376
377 void run() {
378 invoke(indices());
379 }
380 };
381
387 template<typename Invoker>
388 struct state : state_base {
389 const attributes attr;
390 Invoker i;
391
392 state(const attributes& attr, Invoker&& i)
393 : attr(attr),
394 i(std::forward<Invoker>(i)) {
395 }
396
397 const attributes get_attributes() override {
398 return attr;
399 }
400
401 void run() override {
402 i.run();
403 }
404 };
405
410 template<typename Invoker>
411 static state_ptr
412 make_state(const attributes& attr, Invoker&& i) {
413 using state_impl = state<Invoker>;
414 return state_ptr{ new state_impl(attr, std::forward<Invoker>(i)) };
415 }
416
421 template<typename... T>
422 using decayed_tuple = std::tuple<typename std::decay<T>::type...>;
423
427 template<typename F, typename... Args>
428 static invoker<decayed_tuple<F, Args...>>
429 make_invoker(F&& func, Args&&... args)
430 {
431 return {
432 decayed_tuple<F, Args...> {
433 std::forward<F>(func), std::forward<Args>(args)...
434 }
435 };
436 }
437
441 void start_thread(state_ptr s);
442 };
443
444 template<typename F, typename... Args>
445 thread::thread(F&& func, Args&&... args)
446 : id_(0) {
447 attributes attr;
448 start_thread(
449 make_state(attr,
450 make_invoker(decay_copy(std::forward<F>(func)),
451 decay_copy(std::forward<Args>(args))...))
452 );
453 }
454
455 inline std::thread::id thread::get_id() const noexcept {
456 return std::thread::id(id_.id_);
457 }
458
459 inline bool
460 operator==(thread::id l, thread::id r) noexcept {
461 return l.id_ == r.id_;
462 }
463
464 inline bool
465 operator!=(thread::id l, thread::id r) noexcept {
466 return !(l == r);
467 }
468
469 template<class C, class T>
470 inline std::basic_ostream<C, T>&
471 operator<<(std::basic_ostream<C, T>& out, thread::id id_) {
472 return out << std::thread::id(id_.id_);
473 }
474 };
475};
476
477#endif
Manage the attributes of a thread.
Definition: thread.hpp:59
sched_policy
Definition: thread.hpp:74
@ sched_other
Definition: thread.hpp:75
@ sched_sporadic
Definition: thread.hpp:78
@ sched_roundrobin
Definition: thread.hpp:77
@ sched_fifo
Definition: thread.hpp:76
const std::string & get_scheduler()
Definition: thread.cpp:142
attributes()
Definition: thread.cpp:68
void set_name(const std::string &name)
Definition: thread.cpp:88
void set_scheduler(const std::string &scheduler)
Definition: thread.cpp:130
void set_scheduler_policy(sched_policy policy)
Definition: thread.cpp:154
void set_priority(int priority)
Definition: thread.cpp:106
sched_policy get_scheduler_policy() const
Definition: thread.cpp:161
sched_attr
Definition: thread.hpp:64
@ sched_explicit
Definition: thread.hpp:67
@ sched_inherit
Definition: thread.hpp:65
void update()
Definition: thread.cpp:231
const std::string & get_name() const
Definition: thread.cpp:100
void set_stack_size(size_t size)
Definition: thread.cpp:118
bool operator==(const attributes &attr) const
Definition: thread.cpp:309
size_t get_stack_size() const
Definition: thread.cpp:124
int get_priority() const
Definition: thread.cpp:112
sched_attr get_scheduler_attr() const
Definition: thread.cpp:148
void commit()
Definition: thread.cpp:167
attributes & operator=(const attributes &attr)
Definition: thread.cpp:298
Definition: thread.hpp:285
Create a thread with thread attributes.
Definition: thread.hpp:251
thread() noexcept=default
thread & operator=(thread &&thread_)
Definition: thread.cpp:332
typename std::enable_if< std::is_same< DecayA, attributes >::value >::type enable_if_attributes
Definition: thread.hpp:279
unsigned size
Definition: tte.h:1
unsigned p
Definition: tte.h:17
unsigned l
Definition: tte.h:13