27 #ifndef RL_UTIL_XENOMAI_THREAD
28 #define RL_UTIL_XENOMAI_THREAD
32 #include <system_error>
33 #include <native/task.h>
34 #include <native/timer.h>
69 friend class ::std::hash<thread::id>;
101 template<
class CharT,
class Traits>
102 friend ::std::basic_ostream<CharT, Traits>&
operator<<(::std::basic_ostream<CharT, Traits>& out,
thread::id id)
106 return out <<
"thread::id of a non-executing thread";
110 return out <<
id.M_thread;
128 template<
typename Callable,
typename... Args>
129 explicit thread(Callable&& f, Args&&... args)
134 ::std::forward<Callable>(f),
135 ::std::forward<Args>(args)...
168 if (this->
M_id !=
id())
175 throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
183 return !(this->
M_id == id());
210 throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
214 template<
typename Rep,
typename Period>
217 ::std::chrono::nanoseconds period_ns = ::std::chrono::duration_cast< ::std::chrono::nanoseconds>(period);
219 int e = ::rt_task_set_periodic(&this->
M_id.
M_thread, TM_NOW, ::rt_timer_ns2ticks(period_ns.count()));
223 throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
227 template<
typename Duration,
typename Rep,
typename Period>
228 void set_periodic(const ::std::chrono::time_point<chrono::system_clock, Duration>& idate, const ::std::chrono::duration<Rep, Period>& period)
230 ::std::chrono::time_point<chrono::system_clock, ::std::chrono::nanoseconds> idate_ns = ::std::chrono::time_point_cast< ::std::chrono::nanoseconds>(idate);
231 ::std::chrono::nanoseconds period_ns = ::std::chrono::duration_cast< ::std::chrono::nanoseconds>(period);
233 int e = ::rt_task_set_periodic(&this->
M_id.
M_thread, ::rt_timer_ns2ticks(idate_ns.time_since_epoch().count()), ::rt_timer_ns2ticks(period_ns.count()));
237 throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
241 template<
typename Clock,
typename Duration,
typename Rep,
typename Period>
242 void set_periodic(const ::std::chrono::time_point<Clock, Duration>& idate, const ::std::chrono::duration<Rep, Period>& period)
244 const typename Clock::time_point c_entry = Clock::now();
246 const ::std::chrono::nanoseconds delta = idate - c_entry;
253 int e = ::rt_task_set_priority(&this->
M_id.
M_thread, prio);
257 throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
267 throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
288 throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
308 template<
typename Callable>
312 func(::
std::forward<Callable>(f))
340 template<
typename Callable>
343 return ::std::make_shared<Impl<Callable>>(::std::forward<Callable>(f));
348 if (!__gthread_active_p())
351 throw ::std::system_error(::std::make_error_code(::std::errc::operation_not_permitted),
"Enable multithreading to use std::thread");
353 throw ::std::system_error(::std::error_code(::std::errc::operation_not_permitted, ::std::generic_category()));
363 throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
372 namespace this_thread
382 rt_task_inquire(::rt_task_self(), &info);
396 inline int set_mode(
const int& clrmask,
const int& setmask)
399 int e = ::rt_task_set_mode(clrmask, setmask, &mode);
403 throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
411 int e = ::rt_task_set_priority(::rt_task_self(), priority);
415 throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
421 int e = ::rt_task_shadow(
nullptr,
nullptr, 0, T_FPU | T_JOINABLE);
425 throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
429 template<
typename Rep,
typename Period>
430 inline void sleep_for(const ::std::chrono::duration<Rep, Period>& rtime)
432 ::std::chrono::nanoseconds ns = ::std::chrono::duration_cast< ::std::chrono::nanoseconds>(rtime);
433 int e = ::rt_task_sleep(::rt_timer_ns2ticks(ns.count()));
437 throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
441 template<
typename Duration>
442 inline void sleep_until(const ::std::chrono::time_point<chrono::system_clock, Duration>& atime)
444 ::std::chrono::time_point<chrono::system_clock, ::std::chrono::nanoseconds> ns = ::std::chrono::time_point_cast< ::std::chrono::nanoseconds>(atime);
445 int e = ::rt_task_sleep_until(::rt_timer_ns2ticks(ns.time_since_epoch().count()));
449 throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
453 template<
typename Clock,
typename Duration>
454 inline void sleep_until(const ::std::chrono::time_point<Clock, Duration>& atime)
461 unsigned long int overruns;
462 int e = ::rt_task_wait_period(&overruns);
466 throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
474 int e = ::rt_task_yield();
478 throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
491 size_t operator()(const ::rl::util::xenomai::thread::id&
id)
const
493 return hash< ::xnhandle_t>()(
id.M_thread.opaque);
503 #endif // RL_UTIL_XENOMAI_THREAD