mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 15:15:44 +00:00
rtemscxx: Support building on Unix
This lets you develop unittests on Unix.
This commit is contained in:
@@ -362,17 +362,34 @@ namespace rtems
|
|||||||
Parms p;
|
Parms p;
|
||||||
|
|
||||||
template<size_t Index>
|
template<size_t Index>
|
||||||
static std::__tuple_element_t<Index, Parms>&& declval();
|
static std::tuple_element_t<Index, Parms>&& declval();
|
||||||
|
|
||||||
|
template<size_t... _Indexes> struct _Index_tuple { };
|
||||||
|
|
||||||
|
template<size_t _Num>
|
||||||
|
struct _Build_index_tuple
|
||||||
|
{
|
||||||
|
#if __has_builtin(__make_integer_seq)
|
||||||
|
template<typename, size_t... _Indices>
|
||||||
|
using _IdxTuple = _Index_tuple<_Indices...>;
|
||||||
|
|
||||||
|
// Clang defines __make_integer_seq for this purpose.
|
||||||
|
using __type = __make_integer_seq<_IdxTuple, size_t, _Num>;
|
||||||
|
#else
|
||||||
|
// For GCC and other compilers, use __integer_pack instead.
|
||||||
|
using __type = _Index_tuple<__integer_pack(_Num)...>;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
template<size_t... Ind>
|
template<size_t... Ind>
|
||||||
auto invoke(std::_Index_tuple<Ind...>)
|
auto invoke(_Index_tuple<Ind...>)
|
||||||
noexcept(noexcept(std::invoke(declval<Ind>()...)))
|
noexcept(noexcept(std::invoke(declval<Ind>()...)))
|
||||||
-> decltype(std::invoke(declval<Ind>()...)) {
|
-> decltype(std::invoke(declval<Ind>()...)) {
|
||||||
return std::invoke(std::get<Ind>(std::move(p))...);
|
return std::invoke(std::get<Ind>(std::move(p))...);
|
||||||
}
|
}
|
||||||
|
|
||||||
using indices =
|
using indices =
|
||||||
typename std::_Build_index_tuple<std::tuple_size<Parms>::value>::__type;
|
typename _Build_index_tuple<std::tuple_size<Parms>::value>::__type;
|
||||||
|
|
||||||
void run() {
|
void run() {
|
||||||
invoke(indices());
|
invoke(indices());
|
||||||
@@ -453,7 +470,13 @@ namespace rtems
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline std::thread::id thread::get_id() const noexcept {
|
inline std::thread::id thread::get_id() const noexcept {
|
||||||
|
#ifdef __clang__
|
||||||
|
/* clang does not allow construction of std::thread::id with
|
||||||
|
an id so fail this call */
|
||||||
|
return std::thread::id();
|
||||||
|
#else
|
||||||
return std::thread::id(id_.id_);
|
return std::thread::id(id_.id_);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
@@ -469,7 +492,11 @@ namespace rtems
|
|||||||
template<class C, class T>
|
template<class C, class T>
|
||||||
inline std::basic_ostream<C, T>&
|
inline std::basic_ostream<C, T>&
|
||||||
operator<<(std::basic_ostream<C, T>& out, thread::id id_) {
|
operator<<(std::basic_ostream<C, T>& out, thread::id id_) {
|
||||||
|
#ifdef __clang__
|
||||||
|
return out << id_.id_;
|
||||||
|
#else
|
||||||
return out << std::thread::id(id_.id_);
|
return out << std::thread::id(id_.id_);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -36,7 +36,12 @@
|
|||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#ifdef __rtems__
|
||||||
#include <rtems.h>
|
#include <rtems.h>
|
||||||
|
#define MINIMUM_STACK_SIZE RTEMS_MINIMUM_STACK_SIZE
|
||||||
|
#else /* __rtems__ */
|
||||||
|
#define MINIMUM_STACK_SIZE (8 * 1024UL)
|
||||||
|
#endif /* __rtems__ */
|
||||||
|
|
||||||
#if HAVE_GET_SCHEDULER_NAME
|
#if HAVE_GET_SCHEDULER_NAME
|
||||||
extern "C" bool get_scheduler_name(rtems_id sid, char* name);
|
extern "C" bool get_scheduler_name(rtems_id sid, char* name);
|
||||||
@@ -53,6 +58,17 @@ bool get_scheduler_name(rtems_id sid, char* name)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#include <pthread_np.h>
|
||||||
|
static inline int pthread_getattr_np(pthread_t p, pthread_attr_t *a) {
|
||||||
|
return ::pthread_attr_get_np(p, a);
|
||||||
|
}
|
||||||
|
#endif /* __FreeBSD__ */
|
||||||
|
|
||||||
|
#ifdef SCHED_SPORADIC
|
||||||
|
#define HAVE_SCHED_SPORADIC 1
|
||||||
|
#endif /* SCHED_SPORADIC */
|
||||||
|
|
||||||
namespace rtems
|
namespace rtems
|
||||||
{
|
{
|
||||||
namespace thread
|
namespace thread
|
||||||
@@ -67,7 +83,7 @@ namespace rtems
|
|||||||
|
|
||||||
attributes::attributes()
|
attributes::attributes()
|
||||||
: priority(-1),
|
: priority(-1),
|
||||||
stack_size(RTEMS_MINIMUM_STACK_SIZE),
|
stack_size(MINIMUM_STACK_SIZE),
|
||||||
attr(sched_inherit),
|
attr(sched_inherit),
|
||||||
policy(sched_fifo)
|
policy(sched_fifo)
|
||||||
{
|
{
|
||||||
@@ -168,15 +184,15 @@ namespace rtems
|
|||||||
{
|
{
|
||||||
pthread_t pid = ::pthread_self();
|
pthread_t pid = ::pthread_self();
|
||||||
|
|
||||||
system_error_check(::pthread_setname_np(pid, name.c_str()),
|
system_error_check(
|
||||||
|
::pthread_setname_np(pid, name.c_str()),
|
||||||
"getting name");
|
"getting name");
|
||||||
|
|
||||||
int spolicy;
|
int spolicy;
|
||||||
struct sched_param sched_param;
|
struct sched_param sched_param;
|
||||||
|
|
||||||
system_error_check(::pthread_getschedparam(::pthread_self(),
|
system_error_check(
|
||||||
&spolicy,
|
::pthread_getschedparam(pid, &spolicy, &sched_param),
|
||||||
&sched_param),
|
|
||||||
"getting scheduler parameters");
|
"getting scheduler parameters");
|
||||||
|
|
||||||
switch (policy) {
|
switch (policy) {
|
||||||
@@ -190,8 +206,10 @@ namespace rtems
|
|||||||
spolicy = SCHED_RR;
|
spolicy = SCHED_RR;
|
||||||
break;
|
break;
|
||||||
case sched_sporadic:
|
case sched_sporadic:
|
||||||
|
#ifdef HAVE_SCHED_SPORADIC
|
||||||
spolicy = SCHED_SPORADIC;
|
spolicy = SCHED_SPORADIC;
|
||||||
break;
|
break;
|
||||||
|
#endif /* HAVE_SCHED_SPORADIC */
|
||||||
default:
|
default:
|
||||||
system_error_check(EINVAL, "get scheduler policy");
|
system_error_check(EINVAL, "get scheduler policy");
|
||||||
break;
|
break;
|
||||||
@@ -199,9 +217,8 @@ namespace rtems
|
|||||||
|
|
||||||
sched_param.sched_priority = priority;
|
sched_param.sched_priority = priority;
|
||||||
|
|
||||||
system_error_check(::pthread_setschedparam(::pthread_self(),
|
system_error_check(
|
||||||
spolicy,
|
::pthread_setschedparam(pid, spolicy, &sched_param),
|
||||||
&sched_param),
|
|
||||||
"getting scheduler parameters");
|
"getting scheduler parameters");
|
||||||
|
|
||||||
if (!scheduler.empty()) {
|
if (!scheduler.empty()) {
|
||||||
@@ -212,36 +229,36 @@ namespace rtems
|
|||||||
}
|
}
|
||||||
sname[c] = scheduler[c];
|
sname[c] = scheduler[c];
|
||||||
}
|
}
|
||||||
rtems_name scheduler_name = rtems_build_name(sname[0],
|
#ifdef __rtems__
|
||||||
sname[1],
|
rtems_name scheduler_name = rtems_build_name(
|
||||||
sname[2],
|
sname[0], sname[1], sname[2], sname[3]);
|
||||||
sname[3]);
|
|
||||||
rtems_id scheduler_id;
|
rtems_id scheduler_id;
|
||||||
runtime_error_check(::rtems_scheduler_ident(scheduler_name,
|
runtime_error_check(
|
||||||
&scheduler_id),
|
::rtems_scheduler_ident(scheduler_name, &scheduler_id),
|
||||||
"get scheduler id");
|
"get scheduler id");
|
||||||
// runtime_error_check (::rtems_task_set_scheduler (RTEMS_SELF,
|
// runtime_error_check (::rtems_task_set_scheduler (RTEMS_SELF,
|
||||||
// scheduler_id,
|
// scheduler_id,
|
||||||
// 1),
|
// 1),
|
||||||
// "set scheduler id");
|
// "set scheduler id");
|
||||||
|
#endif /* __rtems__ */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
attributes::update()
|
attributes::update()
|
||||||
{
|
{
|
||||||
char buf[32];
|
pthread_t pid = ::pthread_self();
|
||||||
system_error_check(::pthread_getname_np(::pthread_self(),
|
|
||||||
buf,
|
char buf[64];
|
||||||
sizeof (buf)),
|
system_error_check(
|
||||||
|
::pthread_getname_np(pid, buf, sizeof (buf)),
|
||||||
"getting name");
|
"getting name");
|
||||||
name = buf;
|
name = buf;
|
||||||
|
|
||||||
int spolicy;
|
int spolicy;
|
||||||
struct sched_param sched_param;
|
struct sched_param sched_param;
|
||||||
system_error_check(::pthread_getschedparam(::pthread_self(),
|
system_error_check(
|
||||||
&spolicy,
|
::pthread_getschedparam(pid, &spolicy, &sched_param),
|
||||||
&sched_param),
|
|
||||||
"getting scheduler parameters");
|
"getting scheduler parameters");
|
||||||
|
|
||||||
switch (spolicy) {
|
switch (spolicy) {
|
||||||
@@ -254,9 +271,11 @@ namespace rtems
|
|||||||
case SCHED_RR:
|
case SCHED_RR:
|
||||||
policy = sched_roundrobin;
|
policy = sched_roundrobin;
|
||||||
break;
|
break;
|
||||||
|
#ifdef HAVE_SCHED_SPORADIC
|
||||||
case SCHED_SPORADIC:
|
case SCHED_SPORADIC:
|
||||||
policy = sched_sporadic;
|
policy = sched_sporadic;
|
||||||
break;
|
break;
|
||||||
|
#endif /* HAVE_SCHED_SPORADIC */
|
||||||
default:
|
default:
|
||||||
system_error_check(EINVAL, "get scheduler policy");
|
system_error_check(EINVAL, "get scheduler policy");
|
||||||
break;
|
break;
|
||||||
@@ -264,13 +283,22 @@ namespace rtems
|
|||||||
priority = sched_param.sched_priority;
|
priority = sched_param.sched_priority;
|
||||||
|
|
||||||
pthread_attr_t pattr;
|
pthread_attr_t pattr;
|
||||||
system_error_check(::pthread_getattr_np(::pthread_self(), &pattr),
|
system_error_check(
|
||||||
|
::pthread_attr_init(&pattr), "attribute init");
|
||||||
|
|
||||||
|
system_error_check(
|
||||||
|
::pthread_getattr_np(pid, &pattr),
|
||||||
"getting thread attributes");
|
"getting thread attributes");
|
||||||
system_error_check(::pthread_attr_getstacksize(&pattr, &stack_size),
|
system_error_check(
|
||||||
|
::pthread_attr_getstacksize(&pattr, &stack_size),
|
||||||
"getting stack size");
|
"getting stack size");
|
||||||
int inheritsched = 0;
|
int inheritsched = 0;
|
||||||
system_error_check(::pthread_attr_getinheritsched(&pattr, &inheritsched),
|
system_error_check(
|
||||||
"getting inherited sheduler attribute");
|
::pthread_attr_getinheritsched(&pattr, &inheritsched),
|
||||||
|
"getting inherited scheduler attribute");
|
||||||
|
|
||||||
|
::pthread_attr_destroy(&pattr);
|
||||||
|
|
||||||
switch (inheritsched) {
|
switch (inheritsched) {
|
||||||
case PTHREAD_INHERIT_SCHED:
|
case PTHREAD_INHERIT_SCHED:
|
||||||
attr = sched_inherit;
|
attr = sched_inherit;
|
||||||
@@ -283,8 +311,11 @@ namespace rtems
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __rtems__
|
||||||
rtems_id scheduler_id;
|
rtems_id scheduler_id;
|
||||||
runtime_error_check(::rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id));
|
runtime_error_check(
|
||||||
|
::rtems_task_get_scheduler(RTEMS_SELF, &scheduler_id));
|
||||||
|
#endif /* __rtems__ */
|
||||||
#if HAVE_GET_SCHEDULER_NAME
|
#if HAVE_GET_SCHEDULER_NAME
|
||||||
char name[5];
|
char name[5];
|
||||||
if (!get_scheduler_name(scheduler_id, &name[0])) {
|
if (!get_scheduler_name(scheduler_id, &name[0])) {
|
||||||
@@ -378,14 +409,8 @@ namespace rtems
|
|||||||
const attributes attr = s->get_attributes();
|
const attributes attr = s->get_attributes();
|
||||||
|
|
||||||
pthread_attr_t pattr;
|
pthread_attr_t pattr;
|
||||||
|
system_error_check(
|
||||||
system_error_check(::pthread_attr_init(&pattr),
|
::pthread_attr_init(&pattr), "attribute init");
|
||||||
"attribute init");
|
|
||||||
|
|
||||||
struct sched_param param;
|
|
||||||
param.sched_priority = attr.get_priority();
|
|
||||||
system_error_check(::pthread_attr_setschedparam(&pattr, ¶m),
|
|
||||||
"set sched param");
|
|
||||||
|
|
||||||
int spolicy;
|
int spolicy;
|
||||||
switch (attr.get_scheduler_policy()) {
|
switch (attr.get_scheduler_policy()) {
|
||||||
@@ -396,13 +421,16 @@ namespace rtems
|
|||||||
spolicy = SCHED_RR;
|
spolicy = SCHED_RR;
|
||||||
break;
|
break;
|
||||||
case attributes::sched_sporadic:
|
case attributes::sched_sporadic:
|
||||||
|
#ifdef HAVE_SCHED_SPORADIC
|
||||||
spolicy = SCHED_SPORADIC;
|
spolicy = SCHED_SPORADIC;
|
||||||
break;
|
break;
|
||||||
|
#endif /* HAVE_SCHED_SPORADIC */
|
||||||
default:
|
default:
|
||||||
spolicy = SCHED_FIFO;
|
spolicy = SCHED_FIFO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
system_error_check(::pthread_attr_setschedpolicy(&pattr, spolicy),
|
system_error_check(
|
||||||
|
::pthread_attr_setschedpolicy(&pattr, spolicy),
|
||||||
"set scheduler policy");
|
"set scheduler policy");
|
||||||
|
|
||||||
if (attr.get_scheduler_attr() == attributes::sched_inherit) {
|
if (attr.get_scheduler_attr() == attributes::sched_inherit) {
|
||||||
@@ -412,22 +440,28 @@ namespace rtems
|
|||||||
::pthread_attr_setinheritsched(&pattr, PTHREAD_EXPLICIT_SCHED);
|
::pthread_attr_setinheritsched(&pattr, PTHREAD_EXPLICIT_SCHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
system_error_check(::pthread_attr_setstacksize(&pattr,
|
#ifndef __linux__
|
||||||
attr.get_stack_size()),
|
struct sched_param param;
|
||||||
|
param.sched_priority = attr.get_priority();
|
||||||
|
system_error_check(
|
||||||
|
::pthread_attr_setschedparam(&pattr, ¶m),
|
||||||
|
"set sched param");
|
||||||
|
|
||||||
|
system_error_check(
|
||||||
|
::pthread_attr_setstacksize(&pattr, attr.get_stack_size()),
|
||||||
"set stack size");
|
"set stack size");
|
||||||
|
#endif /* __linux__ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hold the new thread in the state's run handler until the rest
|
* Hold the new thread in the state's run handler until the rest
|
||||||
* of the thread is set up after the create call.
|
* of the thread is set up after the create call.
|
||||||
*/
|
*/
|
||||||
system_error_check(::pthread_create(&id_.id_,
|
system_error_check(
|
||||||
&pattr,
|
::pthread_create(&id_.id_, &pattr, thread_generic_entry, s.get()),
|
||||||
thread_generic_entry,
|
|
||||||
s.get()),
|
|
||||||
"create thread");
|
"create thread");
|
||||||
|
|
||||||
system_error_check(::pthread_setname_np(id_.id_,
|
system_error_check(
|
||||||
attr.get_name().c_str()),
|
::pthread_setname_np(id_.id_, attr.get_name().c_str()),
|
||||||
"setting thread name");
|
"setting thread name");
|
||||||
|
|
||||||
::pthread_attr_destroy(&pattr);
|
::pthread_attr_destroy(&pattr);
|
||||||
|
|||||||
Reference in New Issue
Block a user