27 #pragma GCC system_header
30 #include "cxx/ipc_basics"
31 #include "cxx/capability.h"
33 #if defined(__GXX_RTTI) && !defined(L4_NO_RTTI)
35 typedef std::type_info
const *L4_std_type_info_ptr;
36 # define L4_KOBJECT_META_RTTI(type) (&typeid(type))
37 inline char const *L4_kobject_type_name(L4_std_type_info_ptr n) noexcept
38 {
return n ? n->name() : 0; }
40 typedef void const *L4_std_type_info_ptr;
41 # define L4_KOBJECT_META_RTTI(type) (0)
42 inline char const *L4_kobject_type_name(L4_std_type_info_ptr) noexcept
51 template<
unsigned char A,
unsigned char B>
52 struct Max {
enum { Res = A > B ? A : B }; };
93 template<
long P,
typename T>
108 struct Iface_list_end
110 typedef Iface_list_end type;
111 static bool contains(
long) noexcept {
return false; }
122 template<
typename I,
typename N = Iface_list_end>
125 typedef Iface_list<I, N> type;
127 typedef typename I::iface_type iface_type;
130 enum { Proto = I::Proto };
132 static bool contains(
long proto) noexcept
133 {
return (proto == Proto) || Next::contains(proto); }
137 template<
typename I,
typename N>
138 struct Iface_list<Iface<
PROTO_EMPTY, I>, N> : N {};
141 template<
long P,
typename N>
142 struct Iface_list<Iface<P, void>, N> : N {};
152 template<
typename I,
typename L >
155 template<
typename I >
156 struct _In_list<I, Iface_list_end> :
False {};
158 template<
typename I,
typename N >
159 struct _In_list<I, Iface_list<I, N> > :
True {};
161 template<
typename I,
typename I2,
typename N >
162 struct _In_list<I, Iface_list<I2, N> > : _In_list<I, typename N::type> {};
164 template<
typename I,
typename L>
165 struct In_list : _In_list<typename I::type, typename L::type> {};
174 template<
bool ADD,
typename I,
typename L>
175 struct _Iface_list_add;
177 template<
typename I,
typename L>
178 struct _Iface_list_add<false, I, L> : L {};
180 template<
typename I,
typename L>
181 struct _Iface_list_add<true, I, L> : Iface_list<I, L> {};
188 template<
typename I,
typename L >
189 struct Iface_list_add :
191 !In_list<I, typename L::type>::value, I, typename L::type>
201 template<
typename I1,
typename I2 >
202 struct __Iface_conflict :
Bool<I1::Proto != PROTO_EMPTY && I1::Proto == I2::Proto> {};
204 template<
typename I >
205 struct __Iface_conflict<I, I> :
False {};
211 template<
typename I,
typename LIST >
212 struct _Iface_conflict;
214 template<
typename I >
215 struct _Iface_conflict<I, Iface_list_end> :
False {};
217 template<
typename I,
typename I2,
typename LIST >
218 struct _Iface_conflict<I, Iface_list<I2, LIST> > :
219 Bool<__Iface_conflict<I, I2>::value || _Iface_conflict<I, typename LIST::type>::value>
226 template<
typename I,
typename LIST >
227 struct Iface_conflict : _Iface_conflict<typename I::type, typename LIST::type> {};
234 template<
typename L1,
typename L2 >
237 template<
typename L >
238 struct _Merge_list<Iface_list_end, L> : L {};
240 template<
typename I,
typename L1,
typename L2 >
241 struct _Merge_list<Iface_list<I, L1>, L2> :
242 _Merge_list<typename L1::type, typename Iface_list_add<I, L2>::type> {};
244 template<
typename L1,
typename L2>
245 struct Merge_list : _Merge_list<typename L1::type, typename L2::type> {};
252 template<
typename L1,
typename L2 >
255 template<
typename L >
256 struct _Conflict<Iface_list_end, L> :
False {};
258 template<
typename I,
typename L1,
typename L2 >
259 struct _Conflict<Iface_list<I, L1>, L2> :
260 Bool<Iface_conflict<I, typename L2::type>::value
261 || _Conflict<typename L1::type, typename L2::type>::value> {};
263 template<
typename L1,
typename L2 >
264 struct Conflict : _Conflict<typename L1::type, typename L2::type> {};
273 template<
typename LIST>
278 struct _P_dispatch<Iface_list_end>
280 template<
typename THIS,
typename A1,
typename A2 >
281 static int f(THIS *,
long, A1, A2 &) noexcept
287 template<
typename I,
typename LIST >
288 struct _P_dispatch<Iface_list<I, LIST> >
291 template<
typename THIS,
typename A1,
typename A2 >
292 static int _f(THIS
self, A1, A2 &a2,
True::type)
294 return self->dispatch_meta_request(a2);
298 template<
typename THIS,
typename A1,
typename A2 >
299 static int _f(THIS
self, A1 a1, A2 &a2,
False::type)
301 return self->p_dispatch(
reinterpret_cast<typename I::iface_type *
>(0),
306 template<
typename THIS,
typename A1,
typename A2 >
307 static int f(THIS *
self,
long proto, A1 a1, A2 &a2)
309 if (I::Proto == proto)
312 return _P_dispatch<typename LIST::type>::f(
self, proto, a1, a2);
317 template<
typename LIST>
322 template<
typename RPC>
struct Default_op;
329 typedef void opcode_type;
335 template<
typename O1,
typename O2,
typename RPCS>
336 struct _Rpc : _Rpc<typename RPCS::next::rpc, O2, typename RPCS::next>::type {};
339 template<
typename O1,
typename O2>
340 struct _Rpc<O1, O2, Rpcs_end> {};
342 template<
typename OP,
typename RPCS>
343 struct _Rpc<OP, OP, RPCS> : RPCS
348 template<
typename OP,
typename RPCS>
349 struct Rpc : _Rpc<typename RPCS::rpc, OP, RPCS> {};
351 template<
typename T,
unsigned CODE>
354 template<
bool,
typename>
struct Invalid_opcode {};
355 template<
typename X>
struct Invalid_opcode<true, X>;
358 template<
typename U, U>
struct _chk;
359 template<
typename U>
static long _opc(_chk<int, U::Opcode> *);
360 template<
typename U>
static char _opc(...);
362 template<
unsigned SZ,
typename U>
363 struct _Opc {
enum { value = CODE }; };
366 struct _Opc<sizeof(long), U> {
enum { value =
U::Opcode }; };
369 enum { value = _Opc<sizeof(_opc<T>(0)), T>::value };
370 Invalid_opcode<(value < CODE), T> invalid_opcode;
374 template<
typename OPCODE,
unsigned O,
typename ...X>
378 template<
typename OPCODE,
unsigned O,
typename R,
typename ...X>
390 enum {
Opcode = _Get_opcode<R, O>::value };
392 template<
typename Y>
struct Rpc : Typeid::Detail::Rpc<Y, _Rpcs> {};
395 template<
typename OPCODE,
unsigned O,
typename R>
396 struct _Rpcs<OPCODE, O, Default_op<R> >
401 typedef void opcode_type;
409 template<
typename Y>
struct Rpc : Typeid::Detail::Rpc<Y, _Rpcs> {};
421 template<
typename CLASS>
426 typedef void opcode_type;
437 template<
typename ...RPCS>
448 template<
typename OPCODE_TYPE>
454 template<
typename ...RPCS>
463 template<
typename OPERATION>
474 template<
typename ...ARG>
477 template<
typename CLASS>
481 Rights(
unsigned rights) noexcept : rights(rights) {}
482 unsigned operator & (
unsigned rhs)
const noexcept {
return rights & rhs; }
520 static unsigned char max(
unsigned char a,
unsigned char b) noexcept
521 {
return a > b ? a : b; }
537 Demand(
unsigned char caps = 0,
unsigned char flags = 0,
538 unsigned char mem = 0,
unsigned char ports = 0) noexcept
539 : caps(caps), flags(flags), mem(mem), ports(ports) {}
543 {
return caps == 0 && mem == 0 && ports == 0 && flags == 0; }
548 return Demand(
max(caps, rhs.caps), flags | rhs.flags,
549 max(mem, rhs.mem),
max(ports, rhs.ports));
561 template<
unsigned char CAPS = 0,
unsigned char FLAGS = 0,
562 unsigned char MEM = 0,
unsigned char PORTS = 0>
582 template<
typename D1,
typename D2>
584 D1::Flags | D2::Flags,
585 __I::Max<D1::Mem, D2::Mem>::Res,
586 __I::Max<D1::Ports, D2::Ports>::Res>
589 L4_std_type_info_ptr _type;
594 L4_std_type_info_ptr type() const noexcept {
return _type; }
595 Type_info const *base(
unsigned idx)
const noexcept {
return _bases[idx]; }
596 unsigned num_bases() const noexcept {
return _num_bases; }
597 long proto() const noexcept {
return _proto; }
598 char const *name() const noexcept {
return L4_kobject_type_name(type()); }
599 bool has_proto(
long proto)
const noexcept
601 if (_proto && _proto == proto)
607 for (
unsigned i = 0; i < _num_bases; ++i)
608 if (base(i)->has_proto(proto))
632 typedef typename T::__Kobject_typeid::Demand
Demand;
633 typedef typename T::__Iface::iface_type Iface;
634 typedef typename T::__Iface_list Iface_list;
640 static Type_info const *
id() noexcept {
return &T::__Kobject_typeid::_m; }
650 {
return T::__Kobject_typeid::Demand(); }
669 template<
typename THIS,
typename A1,
typename A2>
699 #define L4____GEN_TI(t...) \
700 Type_info const t::__Kobject_typeid::_m = \
702 L4_KOBJECT_META_RTTI(Derived), \
703 &t::__Kobject_typeid::_b[0], \
704 sizeof(t::__Kobject_typeid::_b) / sizeof(t::__Kobject_typeid::_b[0]), \
712 #define L4____GEN_TI_MEMBERS(BASE_DEMAND...) \
714 template< typename T > friend struct Kobject_typeid; \
716 struct __Kobject_typeid { \
717 typedef Type_info::Demand_union_t<S_DEMAND, BASE_DEMAND> Demand; \
718 static Type_info const *const _b[]; \
719 static Type_info const _m; \
722 static long const Protocol = PROTO; \
723 typedef L4::Typeid::Rights<Class> Rights;
757 typename S_DEMAND = Type_info::Demand_t<>
765 typedef Typeid::Iface<PROTO, Derived>
__Iface;
767 typedef Typeid::Merge_list<
768 Typeid::Iface_list<__Iface>,
typename Base::__Iface_list
774 typedef Typeid::Iface_conflict<__Iface, typename Base::__Iface_list> Base_conflict;
775 static_assert(!Base_conflict::value,
"ambiguous protocol ID: protocol also used by Base");
782 L4____GEN_TI_MEMBERS(
typename Base::__Kobject_typeid::Demand)
786 template<
typename Derived,
typename Base,
long PROTO,
typename S_DEMAND>
787 Type_info
const *
const
788 Kobject_t<Derived, Base, PROTO, S_DEMAND>::
789 __Kobject_typeid::_b[] = { &Base::__Kobject_typeid::_m };
795 template<
typename Derived,
typename Base,
long PROTO,
typename S_DEMAND>
796 L4____GEN_TI(Kobject_t<Derived, Base, PROTO, S_DEMAND>);
833 typename S_DEMAND = Type_info::Demand_t<>
841 typedef Typeid::Iface<PROTO, Derived>
__Iface;
843 typedef Typeid::Merge_list<
844 Typeid::Iface_list<__Iface>,
846 typename Base1::__Iface_list,
847 typename Base2::__Iface_list
854 typedef typename Base1::__Iface_list Base1_proto_list;
855 typedef typename Base2::__Iface_list Base2_proto_list;
857 typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
858 typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
859 static_assert(!Base1_conflict::value,
"ambiguous protocol ID, also in Base1");
860 static_assert(!Base2_conflict::value,
"ambiguous protocol ID, also in Base2");
862 typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Bases_conflict;
863 static_assert(!Bases_conflict::value,
"ambiguous protocol IDs in base classes");
868 {
return Base1::cap(); }
874 typename Base1::__Kobject_typeid::Demand,
875 typename Base2::__Kobject_typeid::Demand>
880 operator
Kobject const & () const noexcept
881 {
return *
static_cast<Base1
const *
>(
this); }
885 noexcept(noexcept(((Base1*)0)->dec_refcnt(diff, utcb)))
886 {
return Base1::dec_refcnt(diff, utcb); }
890 template<
typename Derived,
typename Base1,
typename Base2,
891 long PROTO,
typename S_DEMAND >
892 Type_info
const *
const
893 Kobject_2t<Derived, Base1, Base2, PROTO, S_DEMAND>::__Kobject_typeid::_b[] =
895 &Base1::__Kobject_typeid::_m,
896 &Base2::__Kobject_typeid::_m
903 template<
typename Derived,
typename Base1,
typename Base2,
904 long PROTO,
typename S_DEMAND >
905 L4____GEN_TI(Kobject_2t<Derived, Base1, Base2, PROTO, S_DEMAND>);
934 typename S_DEMAND = Type_info::Demand_t<>
942 typedef Typeid::Iface<PROTO, Derived>
__Iface;
944 typedef Typeid::Merge_list<
945 Typeid::Iface_list<__Iface>,
947 typename Base1::__Iface_list,
949 typename Base2::__Iface_list,
950 typename Base3::__Iface_list
958 typedef typename Base1::__Iface_list Base1_proto_list;
959 typedef typename Base2::__Iface_list Base2_proto_list;
960 typedef typename Base3::__Iface_list Base3_proto_list;
962 typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
963 typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
964 typedef Typeid::Iface_conflict<__Iface, Base3_proto_list> Base3_conflict;
966 static_assert(!Base1_conflict::value,
"ambiguous protocol ID, also in Base1");
967 static_assert(!Base2_conflict::value,
"ambiguous protocol ID, also in Base2");
968 static_assert(!Base3_conflict::value,
"ambiguous protocol ID, also in Base3");
970 typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Conflict_bases12;
971 typedef Typeid::Conflict<Base1_proto_list, Base3_proto_list> Conflict_bases13;
972 typedef Typeid::Conflict<Base2_proto_list, Base3_proto_list> Conflict_bases23;
974 static_assert(!Conflict_bases12::value,
"ambiguous protocol IDs in base classes: Base1 and Base2");
975 static_assert(!Conflict_bases13::value,
"ambiguous protocol IDs in base classes: Base1 and Base3");
976 static_assert(!Conflict_bases23::value,
"ambiguous protocol IDs in base classes: Base2 and Base3");
981 {
return Base1::cap(); }
987 typename Base1::__Kobject_typeid::Demand,
988 typename Base2::__Kobject_typeid::Demand>,
989 typename Base3::__Kobject_typeid::Demand>
994 operator
Kobject const & () const noexcept
995 {
return *
static_cast<Base1
const *
>(
this); }
999 noexcept(noexcept(((Base1*)0)->dec_refcnt(diff, utcb)))
1000 {
return Base1::dec_refcnt(diff, utcb); }
1004 template<
typename Derived,
typename Base1,
typename Base2,
typename Base3,
1005 long PROTO,
typename S_DEMAND >
1006 Type_info
const *
const
1007 Kobject_3t<Derived, Base1, Base2, Base3, PROTO, S_DEMAND>::__Kobject_typeid::_b[] =
1009 &Base1::__Kobject_typeid::_m,
1010 &Base2::__Kobject_typeid::_m,
1011 &Base3::__Kobject_typeid::_m
1018 template<
typename Derived,
typename Base1,
typename Base2,
typename Base3,
1019 long PROTO,
typename S_DEMAND >
1020 L4____GEN_TI(Kobject_3t<Derived, Base1, Base2, Base3, PROTO, S_DEMAND>);
1024 #if __cplusplus >= 201103L
1034 template<
typename ...T >
1040 template<
typename T>
1043 template<
typename T1,
typename ...T2>
1044 struct Kobject_demand<T1, T2...> :
1045 Type_info::Demand_union_t<typename Kobject_typeid<T1>::Demand,
1046 Kobject_demand<T2...> >
1049 namespace Typeid_xx {
1051 template<
typename ...LISTS>
1054 template<
typename L>
1055 struct Merge_list<L> : L {};
1057 template<
typename L1,
typename L2>
1058 struct Merge_list<L1, L2> : Typeid::Merge_list<L1, L2> {};
1060 template<
typename L1,
typename L2,
typename ...LISTS>
1061 struct Merge_list<L1, L2, LISTS...> :
1062 Merge_list<typename Typeid::Merge_list<L1, L2>::type, LISTS...> {};
1064 template<
typename I,
typename ...LIST >
1065 struct Iface_conflict;
1067 template<
typename I >
1068 struct Iface_conflict<I> : Typeid::False {};
1070 template<
typename I,
typename L,
typename ...LIST >
1071 struct Iface_conflict<I, L, LIST...> :
1072 Typeid::Bool<Typeid::Iface_conflict<typename I::type, typename L::type>::value
1073 || Iface_conflict<I, LIST...>::value>
1076 template<
typename ...LIST >
1079 template<
typename L >
1080 struct Conflict<L> : Typeid::False {};
1082 template<
typename L1,
typename L2,
typename ...LIST >
1083 struct Conflict<L1, L2, LIST...> :
1084 Typeid::Bool<Typeid::Conflict<typename L1::type, typename L2::type>::value
1085 || Conflict<L1, LIST...>::value
1086 || Conflict<L2, LIST...>::value>
1089 template<
typename T >
1092 static long test(Type_info::Demand
const *);
1093 static char test(...);
1094 enum { value =
sizeof(test((T*)0)) ==
sizeof(
long) };
1097 template<
typename T,
typename ... >
1098 struct First : T {
typedef T type; };
1106 template<
typename Derived,
long PROTO,
typename S_DEMAND,
typename ...BASES>
1107 struct __Kobject_base : BASES...
1110 typedef Derived Class;
1111 typedef Typeid::Iface<PROTO, Derived> __Iface;
1112 typedef Typeid_xx::Merge_list<
1113 Typeid::Iface_list<__Iface>,
1114 typename BASES::__Iface_list...
1117 static void __check_protocols__() noexcept
1119 typedef Typeid_xx::Iface_conflict<__Iface,
typename BASES::__Iface_list...> Conflict;
1120 static_assert(!Conflict::value,
"ambiguous protocol ID, protocol also used in base class");
1122 typedef Typeid_xx::Conflict<
typename BASES::__Iface_list...> Base_conflict;
1123 static_assert(!Base_conflict::value,
"ambiguous protocol IDs in base classes");
1128 {
return Typeid_xx::First<BASES...>::type::cap(); }
1132 L4____GEN_TI_MEMBERS(Kobject_demand<BASES...>)
1136 template<
typename B1,
typename ...>
struct Base1 {
typedef B1 type; };
1140 operator Kobject
const & ()
const noexcept
1141 {
return *
static_cast<typename Base1<BASES...
>::type
const *>(
this); }
1145 noexcept(noexcept(((typename Base1<BASES...>::type *)0)->dec_refcnt(diff, utcb)))
1146 {
return Base1<BASES...>::type::dec_refcnt(diff, utcb); }
1149 template<
typename Derived,
long PROTO,
typename S_DEMAND,
typename ...BASES>
1150 Type_info
const *
const
1151 __Kobject_base<Derived, PROTO, S_DEMAND, BASES...>::__Kobject_typeid::_b[] =
1153 (&BASES::__Kobject_typeid::_m)...
1156 template<
typename Derived,
long PROTO,
typename S_DEMAND,
typename ...BASES>
1157 L4____GEN_TI(__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>);
1161 template<
typename Derived,
long PROTO,
bool HAS_DEMAND,
typename DEMAND,
typename ...ARGS >
1162 struct __Kobject_x_proto;
1165 template<
typename Derived,
long PROTO,
typename DEMAND,
typename ...BASES>
1166 struct __Kobject_x_proto<Derived, PROTO, true, DEMAND, BASES...> :
1167 __Kobject_base<Derived, PROTO, DEMAND, BASES...> {};
1170 template<
typename Derived,
long PROTO,
typename B1,
typename ...BASES>
1171 struct __Kobject_x_proto<Derived, PROTO, false, B1, BASES...> :
1172 __Kobject_base<Derived, PROTO, Type_info::Demand_t<>, B1, BASES...> {};
1181 template<
long P = PROTO_EMPTY >
1197 template<
typename Derived,
typename ...ARGS >
1200 template<
typename Derived,
typename A,
typename ...ARGS >
1202 __Kobject_x_proto<Derived, PROTO_ANY, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1205 template<
typename Derived,
long PROTO,
typename A,
typename ...ARGS >
1207 __Kobject_x_proto<Derived, PROTO, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1214 #undef L4____GEN_TI_MEMBERS