L4Re Operating System Framework
Interface and Usage Documentation
•All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
__typeinfo.h
Go to the documentation of this file.
1
5/*
6 * Copyright (C) 2014-2017, 2019, 2022-2024 Kernkonzept GmbH.
7 * Author(s): Alexander Warg <alexander.warg@kernkonzept.com>
8 */
9/*
10 * (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>
11 * economic rights: Technische Universität Dresden (Germany)
12 *
13 * License: see LICENSE.spdx (in this directory or the directories above)
14 */
15#pragma once
16#pragma GCC system_header
17
18#include "cxx/types"
19#include "cxx/ipc_basics"
20#include "cxx/capability.h"
21
22#if defined(__GXX_RTTI) && !defined(L4_NO_RTTI)
23# include <typeinfo>
24 typedef std::type_info const *L4_std_type_info_ptr;
25# define L4_KOBJECT_META_RTTI(type) (&typeid(type))
26 inline char const *L4_kobject_type_name(L4_std_type_info_ptr n) noexcept
27 { return n ? n->name() : 0; }
28#else
29 typedef void const *L4_std_type_info_ptr;
30# define L4_KOBJECT_META_RTTI(type) (0)
31 inline char const *L4_kobject_type_name(L4_std_type_info_ptr) noexcept
32 { return 0; }
33#endif
34
35namespace L4 {
36 typedef int Opcode;
37// internal max helpers
38namespace __I {
39 // internal max of A nd B helper
40 template< unsigned char A, unsigned char B>
41 struct Max { enum { Res = A > B ? A : B }; };
42} // namespace __I
43
44enum
45{
50};
51
66namespace Typeid {
72 using namespace L4::Types;
73
74 /*********************/
82 template<long P, typename T>
83 struct Iface
84 {
85 typedef Iface type;
86 typedef T iface_type;
87 enum { Proto = P };
88 };
89
90
91 /*********************/
97 struct Iface_list_end
98 {
99 typedef Iface_list_end type;
100 static bool contains(long) noexcept { return false; }
101 };
102
103
111 template<typename I, typename N = Iface_list_end>
112 struct Iface_list
113 {
114 typedef Iface_list<I, N> type;
115
116 typedef typename I::iface_type iface_type;
117 typedef N Next;
118
119 enum { Proto = I::Proto };
120
121 static bool contains(long proto) noexcept
122 { return (proto == Proto) || Next::contains(proto); }
123 };
124
125 // do not insert PROTO_EMPTY interfaces
126 template<typename I, typename N>
127 struct Iface_list<Iface<PROTO_EMPTY, I>, N> : N {};
128
129 // do not insert 'void' type interfaces
130 template<long P, typename N>
131 struct Iface_list<Iface<P, void>, N> : N {};
132
133
134 /*********************/
135 /*
136 * \internal
137 * Test if an interface I is in list L
138 * \tparam I Interface for lookup
139 * \tparam L Iface_list for search
140 */
141 template< typename I, typename L >
142 struct _In_list;
143
144 template< typename I >
145 struct _In_list<I, Iface_list_end> : False {};
146
147 template< typename I, typename N >
148 struct _In_list<I, Iface_list<I, N> > : True {};
149
150 template< typename I, typename I2, typename N >
151 struct _In_list<I, Iface_list<I2, N> > : _In_list<I, typename N::type> {};
152
153 template<typename I, typename L>
154 struct In_list : _In_list<typename I::type, typename L::type> {};
155
156
157 /************/
158 /*
159 * \internal
160 * Add Helper: add I to interface list L if ADD is true
161 * \ingroup l4_cxx_ipc_internal
162 */
163 template< bool ADD, typename I, typename L>
164 struct _Iface_list_add;
165
166 template< typename I, typename L>
167 struct _Iface_list_add<false, I, L> : L {};
168
169 template< typename I, typename L>
170 struct _Iface_list_add<true, I, L> : Iface_list<I, L> {};
171
172 /*
173 * \internal
174 * Add Helper: add I to interface list L if not already in L.
175 * \ingroup l4_cxx_ipc_internal
176 */
177 template< typename I, typename L >
178 struct Iface_list_add :
179 _Iface_list_add<
180 !In_list<I, typename L::type>::value, I, typename L::type>
181 {};
182
183 /************/
184 /*
185 * \internal
186 * Helper: checking for a conflict between I2 and I2.
187 * A conflict means I1 and I2 have the same protocol ID but a different
188 * iface_type.
189 */
190 template< typename I1, typename I2 >
191 struct __Iface_conflict : Bool<I1::Proto != PROTO_EMPTY && I1::Proto == I2::Proto> {};
192
193 template< typename I >
194 struct __Iface_conflict<I, I> : False {};
195
196 /*
197 * \internal
198 * Helper: checking for a conflict between I and any interface in LIST.
199 */
200 template< typename I, typename LIST >
201 struct _Iface_conflict;
202
203 template< typename I >
204 struct _Iface_conflict<I, Iface_list_end> : False {};
205
206 template< typename I, typename I2, typename LIST >
207 struct _Iface_conflict<I, Iface_list<I2, LIST> > :
208 Bool<__Iface_conflict<I, I2>::value || _Iface_conflict<I, typename LIST::type>::value>
209 {};
210
215 template< typename I, typename LIST >
216 struct Iface_conflict : _Iface_conflict<typename I::type, typename LIST::type> {};
217
218 /**************/
219 /*
220 * \internal
221 * Helper: merge two interface lists
222 */
223 template< typename L1, typename L2 >
224 struct _Merge_list;
225
226 template< typename L >
227 struct _Merge_list<Iface_list_end, L> : L {};
228
229 template< typename I, typename L1, typename L2 >
230 struct _Merge_list<Iface_list<I, L1>, L2> :
231 _Merge_list<typename L1::type, typename Iface_list_add<I, L2>::type> {};
232
233 template<typename L1, typename L2>
234 struct Merge_list : _Merge_list<typename L1::type, typename L2::type> {};
235
236 /**************/
237 /*
238 * \internal
239 * check for conflicts among all interfaces in L1 with any interfaces in L2.
240 */
241 template< typename L1, typename L2 >
242 struct _Conflict;
243
244 template< typename L >
245 struct _Conflict<Iface_list_end, L> : False {};
246
247 template< typename I, typename L1, typename L2 >
248 struct _Conflict<Iface_list<I, L1>, L2> :
249 Bool<Iface_conflict<I, typename L2::type>::value
250 || _Conflict<typename L1::type, typename L2::type>::value> {};
251
252 template< typename L1, typename L2 >
253 struct Conflict : _Conflict<typename L1::type, typename L2::type> {};
254
255 // to be removed ---------------------------------------
256 // p_dispatch code -- for legacy dispatch ------------------------------
257 /**********************/
258 /*
259 * \internal
260 * helper: Dispatch helper for calling server-side p_dispatch() functions.
261 */
262 template<typename LIST>
263 struct _P_dispatch;
264
265 // No matching dispatcher found
266 template<>
267 struct _P_dispatch<Iface_list_end>
268 {
269 template< typename THIS, typename A1, typename A2 >
270 static int f(THIS *, long, A1, A2 &) noexcept
271 { return -L4_EBADPROTO; }
272 };
273
274
275 // call matching p_dispatch() function
276 template< typename I, typename LIST >
277 struct _P_dispatch<Iface_list<I, LIST> >
278 {
279 // special handling for the meta protocol, to avoid 'using' murx
280 template< typename THIS, typename A1, typename A2 >
281 static int _f(THIS self, A1, A2 &a2, True::type)
282 {
283 return self->dispatch_meta_request(a2);
284 }
285
286 // normal p_dispatch() dispatching
287 template< typename THIS, typename A1, typename A2 >
288 static int _f(THIS self, A1 a1, A2 &a2, False::type)
289 {
290 return self->p_dispatch(reinterpret_cast<typename I::iface_type *>(0),
291 a1, a2);
292 }
293
294 // dispatch function with switch for meta protocol
295 template< typename THIS, typename A1, typename A2 >
296 static int f(THIS *self, long proto, A1 a1, A2 &a2)
297 {
298 if (I::Proto == proto)
299 return _f(self, a1, a2,
300 Bool<I::Proto == static_cast<long>(L4_PROTO_META)>());
301
302 return _P_dispatch<typename LIST::type>::f(self, proto, a1, a2);
303 }
304 };
305
307 template<typename LIST>
308 struct P_dispatch : _P_dispatch<typename LIST::type> {};
309 // end: p_dispatch -------------------------------------------------------
310 // end: to be removed ---------------------------------------
311
312 template<typename RPC> struct Default_op;
313
314 namespace Detail {
315
317 struct Rpcs_end
318 {
319 typedef void opcode_type;
320 typedef Rpcs_end rpc;
321 typedef Rpcs_end type;
322 };
323
325 template<typename O1, typename O2, typename RPCS>
326 struct _Rpc : _Rpc<typename RPCS::next::rpc, O2, typename RPCS::next>::type {};
328
329 template<typename O1, typename O2>
330 struct _Rpc<O1, O2, Rpcs_end> {};
331
332 template<typename OP, typename RPCS>
333 struct _Rpc<OP, OP, RPCS> : RPCS
334 {
335 typedef _Rpc type;
336 };
337
338 template<typename OP, typename RPCS>
339 struct Rpc : _Rpc<typename RPCS::rpc, OP, RPCS> {};
340
341 template<typename T, unsigned CODE>
342 struct _Get_opcode
343 {
344 template<bool, typename> struct Invalid_opcode {};
345 template<typename X> struct Invalid_opcode<true, X>;
346
347 private:
348 template<typename U, U> struct _chk;
349 template<typename U> static long _opc(_chk<int, U::Opcode> *);
350 template<typename U> static char _opc(...);
351
352 template<unsigned SZ, typename U>
353 struct _Opc { enum { value = CODE }; };
354
355 template<typename U>
356 struct _Opc<sizeof(long), U> { enum { value = U::Opcode }; };
357
358 public:
359 enum { value = _Opc<sizeof(_opc<T>(0)), T>::value };
360 Invalid_opcode<(value < CODE), T> invalid_opcode;
361 };
362
364 template<typename OPCODE, unsigned O, typename ...X>
365 struct _Rpcs : Rpcs_end {};
366
368 template<typename OPCODE, unsigned O, typename R, typename ...X>
369 struct _Rpcs<OPCODE, O, R, X...>
370 {
372 typedef _Rpcs type;
374 typedef OPCODE opcode_type;
376 typedef R rpc;
378 typedef typename _Rpcs<OPCODE, _Get_opcode<R, O>::value + 1, X...>::type next;
380 enum { Opcode = _Get_opcode<R, O>::value };
382 template<typename Y> struct Rpc : Typeid::Detail::Rpc<Y, _Rpcs> {};
383 };
384
385 template<typename OPCODE, unsigned O, typename R>
386 struct _Rpcs<OPCODE, O, Default_op<R> >
387 {
389 typedef _Rpcs type;
391 typedef void opcode_type;
393 typedef R rpc;
395 typedef Rpcs_end next;
397 enum { Opcode = -99 };
399 template<typename Y> struct Rpc : Typeid::Detail::Rpc<Y, _Rpcs> {};
400 };
401
402 } // namespace Detail
403
411 template<typename CLASS>
412 struct Raw_ipc
413 {
414 typedef Raw_ipc type;
415 typedef Detail::Rpcs_end next;
416 typedef void opcode_type;
417 };
418
427 template<typename ...RPCS>
428 struct Rpcs : Detail::_Rpcs<L4::Opcode, 0, RPCS...> {};
429
438 template<typename OPCODE_TYPE>
440 {
444 template<typename ...RPCS>
445 struct F : Detail::_Rpcs<OPCODE_TYPE, 0, RPCS...> {};
446 };
447
453 template<typename OPERATION>
454 struct Rpc_nocode : Detail::_Rpcs<void, 0, OPERATION> {};
455
464 template<typename ...ARG>
465 struct Rpcs_sys : Detail::_Rpcs<l4_umword_t, 0, ARG...> {};
466
467 template<typename CLASS>
468 struct Rights
469 {
470 unsigned rights;
471 Rights(unsigned rights) noexcept : rights(rights) {}
472 unsigned operator & (unsigned rhs) const noexcept { return rights & rhs; }
473 };
474
475} // namespace Typeid
476
500{
507 {
508 private:
510 static unsigned char max(unsigned char a, unsigned char b) noexcept
511 { return a > b ? a : b; }
512
513 public:
514 unsigned char caps;
515 unsigned char flags;
516 unsigned char mem;
517 unsigned char ports;
518
526 explicit
527 Demand(unsigned char caps = 0, unsigned char flags = 0,
528 unsigned char mem = 0, unsigned char ports = 0) noexcept
529 : caps(caps), flags(flags), mem(mem), ports(ports) {}
530
532 bool no_demand() const noexcept
533 { return caps == 0 && mem == 0 && ports == 0 && flags == 0; }
534
536 Demand operator | (Demand const &rhs) const noexcept
537 {
538 return Demand(max(caps, rhs.caps), flags | rhs.flags,
539 max(mem, rhs.mem), max(ports, rhs.ports));
540 }
541 };
542
551 template<unsigned char CAPS = 0, unsigned char FLAGS = 0,
552 unsigned char MEM = 0, unsigned char PORTS = 0>
554 {
555 enum
556 {
557 Caps = CAPS,
558 Flags = FLAGS,
559 Mem = MEM,
560 Ports = PORTS
561 };
562 Demand_t() noexcept : Demand(CAPS, FLAGS, MEM, PORTS) {}
563 };
564
572 template<typename D1, typename D2>
573 struct Demand_union_t : Demand_t<__I::Max<D1::Caps, D2::Caps>::Res,
574 D1::Flags | D2::Flags,
575 __I::Max<D1::Mem, D2::Mem>::Res,
576 __I::Max<D1::Ports, D2::Ports>::Res>
577 {};
578
579 L4_std_type_info_ptr _type;
580 Type_info const *const *_bases;
581 unsigned _num_bases;
582 long _proto;
583
584 L4_std_type_info_ptr type() const noexcept { return _type; }
585 Type_info const *base(unsigned idx) const noexcept { return _bases[idx]; }
586 unsigned num_bases() const noexcept { return _num_bases; }
587 long proto() const noexcept { return _proto; }
588 char const *name() const noexcept { return L4_kobject_type_name(type()); }
589 bool has_proto(long proto) const noexcept
590 {
591 if (_proto && _proto == proto)
592 return true;
593
594 if (!proto)
595 return false;
596
597 for (unsigned i = 0; i < _num_bases; ++i)
598 if (base(i)->has_proto(proto))
599 return true;
600
601 return false;
602 }
603};
604
610template<typename T> struct Kobject_typeid
611{
622 typedef typename T::__Kobject_typeid::Demand Demand;
623 typedef typename T::__Iface::iface_type Iface;
624 typedef typename T::__Iface_list Iface_list;
625
630 static Type_info const *id() noexcept { return &T::__Kobject_typeid::_m; }
631
639 static Type_info::Demand demand() noexcept
640 { return T::__Kobject_typeid::Demand(); }
641
642 // to be removed ---------------------------------------
643 // p_dispatch -----------------------------------------------------------
659 template<typename THIS, typename A1, typename A2>
660 static int proto_dispatch(THIS *self, long proto, A1 a1, A2 &a2)
661 { return Typeid::P_dispatch<typename T::__Iface_list>::f(self, proto, a1, a2); }
662 // p_dispatch -----------------------------------------------------------
663 // end: to be removed ---------------------------------------
664};
665
667template<> struct Kobject_typeid<void>
668{
670};
671
680template<typename T>
681inline
682Type_info const *kobject_typeid() noexcept
683{ return Kobject_typeid<T>::id(); }
684
689#define L4____GEN_TI(t...) \
690Type_info const t::__Kobject_typeid::_m = \
691{ \
692 L4_KOBJECT_META_RTTI(Derived), \
693 &t::__Kobject_typeid::_b[0], \
694 sizeof(t::__Kobject_typeid::_b) / sizeof(t::__Kobject_typeid::_b[0]), \
695 PROTO \
696}
697
702#define L4____GEN_TI_MEMBERS(BASE_DEMAND...) \
703private: \
704 template< typename T > friend struct Kobject_typeid; \
705protected: \
706 struct __Kobject_typeid { \
707 typedef Type_info::Demand_union_t<S_DEMAND, BASE_DEMAND> Demand; \
708 static Type_info const *const _b[]; \
709 static Type_info const _m; \
710 }; \
711public: \
712 static long const Protocol = PROTO; \
713 typedef L4::Typeid::Rights<Class> Rights;
714
743template<
744 typename Derived,
745 typename Base,
746 long PROTO = PROTO_ANY,
747 typename S_DEMAND = Type_info::Demand_t<>
748>
749class Kobject_t : public Base
750{
751protected:
753 typedef Derived Class;
755 typedef Typeid::Iface<PROTO, Derived> __Iface;
757 typedef Typeid::Merge_list<
758 Typeid::Iface_list<__Iface>, typename Base::__Iface_list
760
762 static void __check_protocols__() noexcept
763 {
764 typedef Typeid::Iface_conflict<__Iface, typename Base::__Iface_list> Base_conflict;
765 static_assert(!Base_conflict::value, "ambiguous protocol ID: protocol also used by Base");
766 }
767
769 L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
770
771 // Generate the remaining type information
772 L4____GEN_TI_MEMBERS(typename Base::__Kobject_typeid::Demand)
773};
774
775
777template< typename Derived, typename Base, long PROTO, typename S_DEMAND>
778Type_info const *const
780 __Kobject_typeid::_b[] = { &Base::__Kobject_typeid::_m };
782
787template< typename Derived, typename Base, long PROTO, typename S_DEMAND>
789
790
820template<
821 typename Derived,
822 typename Base1,
823 typename Base2,
824 long PROTO = PROTO_ANY,
825 typename S_DEMAND = Type_info::Demand_t<>
826>
827class Kobject_2t : public Base1, public Base2
828{
829protected:
831 typedef Derived Class;
833 typedef Typeid::Iface<PROTO, Derived> __Iface;
835 typedef Typeid::Merge_list<
836 Typeid::Iface_list<__Iface>,
837 Typeid::Merge_list<
838 typename Base1::__Iface_list,
839 typename Base2::__Iface_list
840 >
842
844 static void __check_protocols__() noexcept
845 {
846 typedef typename Base1::__Iface_list Base1_proto_list;
847 typedef typename Base2::__Iface_list Base2_proto_list;
848
849 typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
850 typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
851 static_assert(!Base1_conflict::value, "ambiguous protocol ID, also in Base1");
852 static_assert(!Base2_conflict::value, "ambiguous protocol ID, also in Base2");
853
854 typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Bases_conflict;
855 static_assert(!Bases_conflict::value, "ambiguous protocol IDs in base classes");
856 }
857
858 // disambiguate cap()
859 l4_cap_idx_t cap() const noexcept
860 { return Base1::cap(); }
861
863 L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
864
865 L4____GEN_TI_MEMBERS(Type_info::Demand_union_t<
866 typename Base1::__Kobject_typeid::Demand,
867 typename Base2::__Kobject_typeid::Demand>
868 )
869
870public:
871 // Provide non-ambiguous conversion to Kobject
872 operator Kobject const & () const noexcept
873 { return *static_cast<Base1 const *>(this); }
874
875 // Provide non-ambiguous access of dec_refcnt()
876 l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
877 noexcept(noexcept(static_cast<Base1*>(nullptr)->dec_refcnt(diff, utcb)))
878 { return Base1::dec_refcnt(diff, utcb); }
879};
880
881
883template< typename Derived, typename Base1, typename Base2,
884 long PROTO, typename S_DEMAND >
885Type_info const *const
887{
888 &Base1::__Kobject_typeid::_m,
889 &Base2::__Kobject_typeid::_m
890};
892
897template< typename Derived, typename Base1, typename Base2,
898 long PROTO, typename S_DEMAND >
900
901
902
922template<
923 typename Derived,
924 typename Base1,
925 typename Base2,
926 typename Base3,
927 long PROTO = PROTO_ANY,
928 typename S_DEMAND = Type_info::Demand_t<>
929>
930struct Kobject_3t : Base1, Base2, Base3
931{
932protected:
934 typedef Derived Class;
936 typedef Typeid::Iface<PROTO, Derived> __Iface;
938 typedef Typeid::Merge_list<
939 Typeid::Iface_list<__Iface>,
940 Typeid::Merge_list<
941 typename Base1::__Iface_list,
942 Typeid::Merge_list<
943 typename Base2::__Iface_list,
944 typename Base3::__Iface_list
945 >
946 >
948
950 static void __check_protocols__() noexcept
951 {
952 typedef typename Base1::__Iface_list Base1_proto_list;
953 typedef typename Base2::__Iface_list Base2_proto_list;
954 typedef typename Base3::__Iface_list Base3_proto_list;
955
956 typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
957 typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
958 typedef Typeid::Iface_conflict<__Iface, Base3_proto_list> Base3_conflict;
959
960 static_assert(!Base1_conflict::value, "ambiguous protocol ID, also in Base1");
961 static_assert(!Base2_conflict::value, "ambiguous protocol ID, also in Base2");
962 static_assert(!Base3_conflict::value, "ambiguous protocol ID, also in Base3");
963
964 typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Conflict_bases12;
965 typedef Typeid::Conflict<Base1_proto_list, Base3_proto_list> Conflict_bases13;
966 typedef Typeid::Conflict<Base2_proto_list, Base3_proto_list> Conflict_bases23;
967
968 static_assert(!Conflict_bases12::value, "ambiguous protocol IDs in base classes: Base1 and Base2");
969 static_assert(!Conflict_bases13::value, "ambiguous protocol IDs in base classes: Base1 and Base3");
970 static_assert(!Conflict_bases23::value, "ambiguous protocol IDs in base classes: Base2 and Base3");
971 }
972
973 // disambiguate cap()
974 l4_cap_idx_t cap() const noexcept
975 { return Base1::cap(); }
976
978 L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
979
981 typename Base1::__Kobject_typeid::Demand,
982 typename Base2::__Kobject_typeid::Demand>,
983 typename Base3::__Kobject_typeid::Demand>
984 )
985
986public:
987 // Provide non-ambiguous conversion to Kobject
988 operator Kobject const & () const noexcept
989 { return *static_cast<Base1 const *>(this); }
990
991 // Provide non-ambiguous access of dec_refcnt()
992 l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
993 noexcept(noexcept(static_cast<Base1*>(nullptr)->dec_refcnt(diff, utcb)))
994 { return Base1::dec_refcnt(diff, utcb); }
995};
996
997
999template< typename Derived, typename Base1, typename Base2, typename Base3,
1000 long PROTO, typename S_DEMAND >
1001Type_info const *const
1003{
1004 &Base1::__Kobject_typeid::_m,
1005 &Base2::__Kobject_typeid::_m,
1006 &Base3::__Kobject_typeid::_m
1007};
1009
1014template< typename Derived, typename Base1, typename Base2, typename Base3,
1015 long PROTO, typename S_DEMAND >
1017
1018}
1019
1020#if __cplusplus >= 201103L
1021
1022namespace L4 {
1023
1030template< typename ...T >
1032
1033template<>
1034struct Kobject_demand<> : Type_info::Demand_t<> {};
1035
1036template<typename T>
1037struct Kobject_demand<T> : Kobject_typeid<T>::Demand {};
1038
1039template<typename T1, typename ...T2>
1040struct Kobject_demand<T1, T2...> :
1041 Type_info::Demand_union_t<typename Kobject_typeid<T1>::Demand,
1042 Kobject_demand<T2...> >
1043{};
1044
1045namespace Typeid_xx {
1046
1047 template<typename ...LISTS>
1048 struct Merge_list;
1049
1050 template<typename L>
1051 struct Merge_list<L> : L {};
1052
1053 template<typename L1, typename L2>
1054 struct Merge_list<L1, L2> : Typeid::Merge_list<L1, L2> {};
1055
1056 template<typename L1, typename L2, typename ...LISTS>
1057 struct Merge_list<L1, L2, LISTS...> :
1058 Merge_list<typename Typeid::Merge_list<L1, L2>::type, LISTS...> {};
1059
1060 template< typename I, typename ...LIST >
1061 struct Iface_conflict;
1062
1063 template< typename I >
1064 struct Iface_conflict<I> : Typeid::False {};
1065
1066 template< typename I, typename L, typename ...LIST >
1067 struct Iface_conflict<I, L, LIST...> :
1068 Typeid::Bool<Typeid::Iface_conflict<typename I::type, typename L::type>::value
1069 || Iface_conflict<I, LIST...>::value>
1070 {};
1071
1072 template< typename ...LIST >
1073 struct Conflict;
1074
1075 template< typename L >
1076 struct Conflict<L> : Typeid::False {};
1077
1078 template< typename L1, typename L2, typename ...LIST >
1079 struct Conflict<L1, L2, LIST...> :
1080 Typeid::Bool<Typeid::Conflict<typename L1::type, typename L2::type>::value
1081 || Conflict<L1, LIST...>::value
1082 || Conflict<L2, LIST...>::value>
1083 {};
1084
1085 template< typename T >
1086 struct Is_demand
1087 {
1088 static long test(Type_info::Demand const *);
1089 static char test(...);
1090 enum { value = sizeof(test(static_cast<T*>(nullptr))) == sizeof(long) };
1091 };
1092
1093 template< typename T, typename ... >
1094 struct First : T { typedef T type; };
1095} // Typeid
1096
1102template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
1103struct __Kobject_base : BASES...
1104{
1105protected:
1106 typedef Derived Class;
1107 typedef Typeid::Iface<PROTO, Derived> __Iface;
1108 typedef Typeid_xx::Merge_list<
1109 Typeid::Iface_list<__Iface>,
1110 typename BASES::__Iface_list...
1111 > __Iface_list;
1112
1113 static void __check_protocols__() noexcept
1114 {
1115 typedef Typeid_xx::Iface_conflict<__Iface, typename BASES::__Iface_list...> Conflict;
1116 static_assert(!Conflict::value, "ambiguous protocol ID, protocol also used in base class");
1117
1118 typedef Typeid_xx::Conflict<typename BASES::__Iface_list...> Base_conflict;
1119 static_assert(!Base_conflict::value, "ambiguous protocol IDs in base classes");
1120 }
1121
1122 // disambiguate cap()
1123 l4_cap_idx_t cap() const noexcept
1124 { return Typeid_xx::First<BASES...>::type::cap(); }
1125
1126 L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
1127
1128 L4____GEN_TI_MEMBERS(Kobject_demand<BASES...>)
1129
1130private:
1131 // This function returns the first base class (used below)
1132 template<typename B1, typename ...> struct Base1 { typedef B1 type; };
1133
1134public:
1135 // Provide non-ambiguous conversion to Kobject
1136 operator Kobject const & () const noexcept
1137 { return *static_cast<typename Base1<BASES...>::type const *>(this); }
1138
1139 // Provide non-ambiguous access of dec_refcnt()
1140 l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
1141 noexcept(noexcept(static_cast<typename Base1<BASES...>::type *>(nullptr)
1142 ->dec_refcnt(diff, utcb)))
1143 { return Base1<BASES...>::type::dec_refcnt(diff, utcb); }
1144};
1145
1147template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
1148Type_info const *const
1149__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>::__Kobject_typeid::_b[] =
1150{
1151 (&BASES::__Kobject_typeid::_m)...
1152};
1154
1155template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
1156L4____GEN_TI(__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>);
1157
1158
1159// Test if the there is a Demand argument to Kobject_x
1160template< typename Derived, long PROTO, bool HAS_DEMAND, typename DEMAND, typename ...ARGS >
1161struct __Kobject_x_proto;
1162
1163// YES: pass it to __Kobject_base
1164template< typename Derived, long PROTO, typename DEMAND, typename ...BASES>
1165struct __Kobject_x_proto<Derived, PROTO, true, DEMAND, BASES...> :
1166 __Kobject_base<Derived, PROTO, DEMAND, BASES...> {};
1167
1168// NO: pass it empty Type_info::Demand_t
1169template< typename Derived, long PROTO, typename B1, typename ...BASES>
1170struct __Kobject_x_proto<Derived, PROTO, false, B1, BASES...> :
1171 __Kobject_base<Derived, PROTO, Type_info::Demand_t<>, B1, BASES...> {};
1172
1180template< long P = PROTO_EMPTY >
1181struct Proto_t {};
1182
1196template< typename Derived, typename ...ARGS >
1198
1199template< typename Derived, typename A, typename ...ARGS >
1200struct Kobject_x<Derived, A, ARGS...> :
1201 __Kobject_x_proto<Derived, PROTO_ANY, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1202{};
1203
1204template< typename Derived, long PROTO, typename A, typename ...ARGS >
1205struct Kobject_x<Derived, Proto_t<PROTO>, A, ARGS...> :
1206 __Kobject_x_proto<Derived, PROTO, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1207{};
1208
1209}
1210#endif
1211
1212#undef L4____GEN_TI
1213#undef L4____GEN_TI_MEMBERS
C++ interface for capabilities.
Definition capability.h:219
Helper class to create an L4Re interface class that is derived from two base classes (see L4::Kobject...
Definition __typeinfo.h:828
Derived Class
The target interface type (inheriting from Kobject_t)
Definition __typeinfo.h:831
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
Definition __typeinfo.h:863
static void __check_protocols__() noexcept
Helper to check for protocol conflicts.
Definition __typeinfo.h:844
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition __typeinfo.h:833
Typeid::Merge_list< Typeid::Iface_list< __Iface >, Typeid::Merge_list< typename Base1::__Iface_list, typename Base2::__Iface_list > > __Iface_list
The list of all RPC interfaces provided directly or through inheritance.
Definition __typeinfo.h:841
Helper class to create an L4Re interface class that is derived from a single base class.
Definition __typeinfo.h:750
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition __typeinfo.h:755
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
Definition __typeinfo.h:769
static void __check_protocols__() noexcept
Helper to check for protocol conflicts.
Definition __typeinfo.h:762
Derived Class
The target interface type (inheriting from Kobject_t)
Definition __typeinfo.h:753
Typeid::Merge_list< Typeid::Iface_list< __Iface >, typename Base::__Iface_list > __Iface_list
The list of all RPC interfaces provided directly or through inheritance.
Definition __typeinfo.h:759
Base class for all kinds of kernel objects and remote objects, referenced by capabilities.
Definition kobject:37
Data type for expressing the needed receive buffers at the server-side of an interface.
Definition __typeinfo.h:507
unsigned char mem
number of memory receive buffers.
Definition __typeinfo.h:516
Demand(unsigned char caps=0, unsigned char flags=0, unsigned char mem=0, unsigned char ports=0) noexcept
Make Demand object.
Definition __typeinfo.h:527
unsigned char flags
flags, such as the need for timeouts (TBD).
Definition __typeinfo.h:515
bool no_demand() const noexcept
Definition __typeinfo.h:532
unsigned char caps
number of capability receive buffers.
Definition __typeinfo.h:514
unsigned char ports
number of IO-port receive buffers.
Definition __typeinfo.h:517
Template for defining typical Flags bitmaps.
Definition types:53
signed long l4_mword_t
Signed machine word.
Definition l4int.h:37
unsigned long l4_cap_idx_t
Capability selector type.
Definition types.h:335
@ L4_EBADPROTO
Unsupported protocol.
Definition err.h:51
Type_info const * kobject_typeid() noexcept
Get the L4::Type_info for the L4Re interface given in T.
Definition __typeinfo.h:682
@ L4_PROTO_META
Meta information protocol.
Definition types.h:62
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition utcb.h:56
l4_utcb_t * l4_utcb(void) L4_NOTHROW L4_PURE
Get the UTCB address.
Definition utcb.h:346
#define L4_EXPORT
Attribute to mark functions, variables, and data types as being exported from a library.
Definition compiler.h:210
L4 basic type helpers for C++.
Definition types:20
L4 low-level kernel interface.
int Opcode
Data type for RPC opcodes.
Definition __typeinfo.h:36
@ PROTO_EMPTY
Empty protocol for empty APIs.
Definition __typeinfo.h:49
@ PROTO_ANY
Default protocol used by Kobject_t and Kobject_x.
Definition __typeinfo.h:47
Helper class to create an L4Re interface class that is derived from three base classes (see L4::Kobje...
Definition __typeinfo.h:931
Typeid::Merge_list< Typeid::Iface_list< __Iface >, Typeid::Merge_list< typename Base1::__Iface_list, Typeid::Merge_list< typename Base2::__Iface_list, typename Base3::__Iface_list > > > __Iface_list
The list of all RPC interfaces provided directly or through inheritance.
Definition __typeinfo.h:947
Derived Class
The target interface type (inheriting from Kobject_t)
Definition __typeinfo.h:934
static void __check_protocols__() noexcept
Helper to check for protocol conflicts.
Definition __typeinfo.h:950
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition __typeinfo.h:936
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
Definition __typeinfo.h:978
Get the combined server-side resource requirements for all type T...
Meta object for handling access to type information of Kobjects.
Definition __typeinfo.h:611
static Type_info const * id() noexcept
Get a pointer to teh Kobject type information of T.
Definition __typeinfo.h:630
static int proto_dispatch(THIS *self, long proto, A1 a1, A2 &a2)
Protocol based server-side dispatch function.
Definition __typeinfo.h:660
T::__Kobject_typeid::Demand Demand
Data type expressing the static demand of receive buffers in a server.
Definition __typeinfo.h:622
static Type_info::Demand demand() noexcept
Get the receive-buffer demand for the server providing the interface T.
Definition __typeinfo.h:639
Generic Kobject inheritance template.
Data type for defining protocol numbers.
Template type statically describing demand of receive buffers.
Definition __typeinfo.h:554
Template type statically describing the combination of two Demand object.
Definition __typeinfo.h:577
Dynamic Type Information for L4Re Interfaces.
Definition __typeinfo.h:500
Internal end-of-list marker.
Definition __typeinfo.h:318
R rpc
The RPC type L4::Ipc::Msg::Rpc_call or L4::Ipc::Msg::Rpc_inline_call.
Definition __typeinfo.h:376
_Rpcs< OPCODE, _Get_opcode< R, O >::value+1, X... >::type next
The next RPC in the list or Rpcs_end if this is the last.
Definition __typeinfo.h:378
OPCODE opcode_type
The data type for the opcode.
Definition __typeinfo.h:374
Empty list of RPCs.
Definition __typeinfo.h:365
Use for protocol based dispatch stage.
Definition __typeinfo.h:308
RPCs list for passing raw incoming IPC to the server object.
Definition __typeinfo.h:413
List of RPCs of an interface using a single operation without an opcode.
Definition __typeinfo.h:454
List of RPCs of an interface using a special opcode type.
Definition __typeinfo.h:440
List of RPCs typically used for kernel interfaces.
Definition __typeinfo.h:465
Standard list of RPCs of an interface.
Definition __typeinfo.h:428
Boolean meta type.
Definition types:289
Bool< V > type
The meta type itself.
Definition types:290
False meta value.
Definition types:296
True meta value.
Definition types:300
Message tag data structure.
Definition types.h:153