L4Re Operating System Framework – Interface and Usage Documentation
Loading...
Searching...
No Matches
__typeinfo.h
Go to the documentation of this file.
1
5/*
6 * Copyright (C) 2014-2017, 2019, 2022 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 * This file is part of TUD:OS and distributed under the terms of the
14 * GNU General Public License 2.
15 * Please see the COPYING-GPL-2 file for details.
16 *
17 * As a special exception, you may use this file as part of a free software
18 * library without restriction. Specifically, if other files instantiate
19 * templates or use macros or inline functions from this file, or you compile
20 * this file and link it with other files to produce an executable, this
21 * file does not by itself cause the resulting executable to be covered by
22 * the GNU General Public License. This exception does not however
23 * invalidate any other reasons why the executable file might be covered by
24 * the GNU General Public License.
25 */
26#pragma once
27#pragma GCC system_header
28
29#include "cxx/types"
30#include "cxx/ipc_basics"
31#include "cxx/capability.h"
32
33#if defined(__GXX_RTTI) && !defined(L4_NO_RTTI)
34# include <typeinfo>
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; }
39#else
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
43 { return 0; }
44#endif
45
46namespace L4 {
47 typedef int Opcode;
48// internal max helpers
49namespace __I {
50 // internal max of A nd B helper
51 template< unsigned char A, unsigned char B>
52 struct Max { enum { Res = A > B ? A : B }; };
53} // namespace __I
54
55enum
56{
61};
62
77namespace Typeid {
83 using namespace L4::Types;
84
85 /*********************/
93 template<long P, typename T>
94 struct Iface
95 {
96 typedef Iface type;
97 typedef T iface_type;
98 enum { Proto = P };
99 };
100
101
102 /*********************/
108 struct Iface_list_end
109 {
110 typedef Iface_list_end type;
111 static bool contains(long) noexcept { return false; }
112 };
113
114
122 template<typename I, typename N = Iface_list_end>
123 struct Iface_list
124 {
125 typedef Iface_list<I, N> type;
126
127 typedef typename I::iface_type iface_type;
128 typedef N Next;
129
130 enum { Proto = I::Proto };
131
132 static bool contains(long proto) noexcept
133 { return (proto == Proto) || Next::contains(proto); }
134 };
135
136 // do not insert PROTO_EMPTY interfaces
137 template<typename I, typename N>
138 struct Iface_list<Iface<PROTO_EMPTY, I>, N> : N {};
139
140 // do not insert 'void' type interfaces
141 template<long P, typename N>
142 struct Iface_list<Iface<P, void>, N> : N {};
143
144
145 /*********************/
146 /*
147 * \internal
148 * Test if an interface I is in list L
149 * \tparam I Interface for lookup
150 * \tparam L Iface_list for search
151 */
152 template< typename I, typename L >
153 struct _In_list;
154
155 template< typename I >
156 struct _In_list<I, Iface_list_end> : False {};
157
158 template< typename I, typename N >
159 struct _In_list<I, Iface_list<I, N> > : True {};
160
161 template< typename I, typename I2, typename N >
162 struct _In_list<I, Iface_list<I2, N> > : _In_list<I, typename N::type> {};
163
164 template<typename I, typename L>
165 struct In_list : _In_list<typename I::type, typename L::type> {};
166
167
168 /************/
169 /*
170 * \internal
171 * Add Helper: add I to interface list L if ADD is true
172 * \ingroup l4_cxx_ipc_internal
173 */
174 template< bool ADD, typename I, typename L>
175 struct _Iface_list_add;
176
177 template< typename I, typename L>
178 struct _Iface_list_add<false, I, L> : L {};
179
180 template< typename I, typename L>
181 struct _Iface_list_add<true, I, L> : Iface_list<I, L> {};
182
183 /*
184 * \internal
185 * Add Helper: add I to interface list L if not already in L.
186 * \ingroup l4_cxx_ipc_internal
187 */
188 template< typename I, typename L >
189 struct Iface_list_add :
190 _Iface_list_add<
191 !In_list<I, typename L::type>::value, I, typename L::type>
192 {};
193
194 /************/
195 /*
196 * \internal
197 * Helper: checking for a conflict between I2 and I2.
198 * A conflict means I1 and I2 have the same protocol ID but a different
199 * iface_type.
200 */
201 template< typename I1, typename I2 >
202 struct __Iface_conflict : Bool<I1::Proto != PROTO_EMPTY && I1::Proto == I2::Proto> {};
203
204 template< typename I >
205 struct __Iface_conflict<I, I> : False {};
206
207 /*
208 * \internal
209 * Helper: checking for a conflict between I and any interface in LIST.
210 */
211 template< typename I, typename LIST >
212 struct _Iface_conflict;
213
214 template< typename I >
215 struct _Iface_conflict<I, Iface_list_end> : False {};
216
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>
220 {};
221
226 template< typename I, typename LIST >
227 struct Iface_conflict : _Iface_conflict<typename I::type, typename LIST::type> {};
228
229 /**************/
230 /*
231 * \internal
232 * Helper: merge two interface lists
233 */
234 template< typename L1, typename L2 >
235 struct _Merge_list;
236
237 template< typename L >
238 struct _Merge_list<Iface_list_end, L> : L {};
239
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> {};
243
244 template<typename L1, typename L2>
245 struct Merge_list : _Merge_list<typename L1::type, typename L2::type> {};
246
247 /**************/
248 /*
249 * \internal
250 * check for conflicts among all interfaces in L1 with any interfaces in L2.
251 */
252 template< typename L1, typename L2 >
253 struct _Conflict;
254
255 template< typename L >
256 struct _Conflict<Iface_list_end, L> : False {};
257
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> {};
262
263 template< typename L1, typename L2 >
264 struct Conflict : _Conflict<typename L1::type, typename L2::type> {};
265
266 // to be removed ---------------------------------------
267 // p_dispatch code -- for legacy dispatch ------------------------------
268 /**********************/
269 /*
270 * \internal
271 * helper: Dispatch helper for calling server-side p_dispatch() functions.
272 */
273 template<typename LIST>
274 struct _P_dispatch;
275
276 // No matching dispatcher found
277 template<>
278 struct _P_dispatch<Iface_list_end>
279 {
280 template< typename THIS, typename A1, typename A2 >
281 static int f(THIS *, long, A1, A2 &) noexcept
282 { return -L4_EBADPROTO; }
283 };
284
285
286 // call matching p_dispatch() function
287 template< typename I, typename LIST >
288 struct _P_dispatch<Iface_list<I, LIST> >
289 {
290 // special handling for the meta protocol, to avoid 'using' murx
291 template< typename THIS, typename A1, typename A2 >
292 static int _f(THIS self, A1, A2 &a2, True::type)
293 {
294 return self->dispatch_meta_request(a2);
295 }
296
297 // normal p_dispatch() dispatching
298 template< typename THIS, typename A1, typename A2 >
299 static int _f(THIS self, A1 a1, A2 &a2, False::type)
300 {
301 return self->p_dispatch(reinterpret_cast<typename I::iface_type *>(0),
302 a1, a2);
303 }
304
305 // dispatch function with switch for meta protocol
306 template< typename THIS, typename A1, typename A2 >
307 static int f(THIS *self, long proto, A1 a1, A2 &a2)
308 {
309 if (I::Proto == proto)
310 return _f(self, a1, a2, Bool<I::Proto == (long)L4_PROTO_META>());
311
312 return _P_dispatch<typename LIST::type>::f(self, proto, a1, a2);
313 }
314 };
315
317 template<typename LIST>
318 struct P_dispatch : _P_dispatch<typename LIST::type> {};
319 // end: p_dispatch -------------------------------------------------------
320 // end: to be removed ---------------------------------------
321
322 template<typename RPC> struct Default_op;
323
324 namespace Detail {
325
327 struct Rpcs_end
328 {
329 typedef void opcode_type;
330 typedef Rpcs_end rpc;
331 typedef Rpcs_end type;
332 };
333
335 template<typename O1, typename O2, typename RPCS>
336 struct _Rpc : _Rpc<typename RPCS::next::rpc, O2, typename RPCS::next>::type {};
338
339 template<typename O1, typename O2>
340 struct _Rpc<O1, O2, Rpcs_end> {};
341
342 template<typename OP, typename RPCS>
343 struct _Rpc<OP, OP, RPCS> : RPCS
344 {
345 typedef _Rpc type;
346 };
347
348 template<typename OP, typename RPCS>
349 struct Rpc : _Rpc<typename RPCS::rpc, OP, RPCS> {};
350
351 template<typename T, unsigned CODE>
352 struct _Get_opcode
353 {
354 template<bool, typename> struct Invalid_opcode {};
355 template<typename X> struct Invalid_opcode<true, X>;
356
357 private:
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(...);
361
362 template<unsigned SZ, typename U>
363 struct _Opc { enum { value = CODE }; };
364
365 template<typename U>
366 struct _Opc<sizeof(long), U> { enum { value = U::Opcode }; };
367
368 public:
369 enum { value = _Opc<sizeof(_opc<T>(0)), T>::value };
370 Invalid_opcode<(value < CODE), T> invalid_opcode;
371 };
372
374 template<typename OPCODE, unsigned O, typename ...X>
375 struct _Rpcs : Rpcs_end {};
376
378 template<typename OPCODE, unsigned O, typename R, typename ...X>
379 struct _Rpcs<OPCODE, O, R, X...>
380 {
382 typedef _Rpcs type;
384 typedef OPCODE opcode_type;
386 typedef R rpc;
388 typedef typename _Rpcs<OPCODE, _Get_opcode<R, O>::value + 1, X...>::type next;
390 enum { Opcode = _Get_opcode<R, O>::value };
392 template<typename Y> struct Rpc : Typeid::Detail::Rpc<Y, _Rpcs> {};
393 };
394
395 template<typename OPCODE, unsigned O, typename R>
396 struct _Rpcs<OPCODE, O, Default_op<R> >
397 {
399 typedef _Rpcs type;
401 typedef void opcode_type;
403 typedef R rpc;
405 typedef Rpcs_end next;
407 enum { Opcode = -99 };
409 template<typename Y> struct Rpc : Typeid::Detail::Rpc<Y, _Rpcs> {};
410 };
411
412 } // namespace Detail
413
421 template<typename CLASS>
422 struct Raw_ipc
423 {
424 typedef Raw_ipc type;
425 typedef Detail::Rpcs_end next;
426 typedef void opcode_type;
427 };
428
437 template<typename ...RPCS>
438 struct Rpcs : Detail::_Rpcs<L4::Opcode, 0, RPCS...> {};
439
448 template<typename OPCODE_TYPE>
450 {
454 template<typename ...RPCS>
455 struct F : Detail::_Rpcs<OPCODE_TYPE, 0, RPCS...> {};
456 };
457
463 template<typename OPERATION>
464 struct Rpc_nocode : Detail::_Rpcs<void, 0, OPERATION> {};
465
474 template<typename ...ARG>
475 struct Rpcs_sys : Detail::_Rpcs<l4_umword_t, 0, ARG...> {};
476
477 template<typename CLASS>
478 struct Rights
479 {
480 unsigned rights;
481 Rights(unsigned rights) noexcept : rights(rights) {}
482 unsigned operator & (unsigned rhs) const noexcept { return rights & rhs; }
483 };
484
485} // namespace Typeid
486
510{
517 {
518 private:
520 static unsigned char max(unsigned char a, unsigned char b) noexcept
521 { return a > b ? a : b; }
522
523 public:
524 unsigned char caps;
525 unsigned char flags;
526 unsigned char mem;
527 unsigned char ports;
528
536 explicit
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) {}
540
542 bool no_demand() const noexcept
543 { return caps == 0 && mem == 0 && ports == 0 && flags == 0; }
544
546 Demand operator | (Demand const &rhs) const noexcept
547 {
548 return Demand(max(caps, rhs.caps), flags | rhs.flags,
549 max(mem, rhs.mem), max(ports, rhs.ports));
550 }
551 };
552
561 template<unsigned char CAPS = 0, unsigned char FLAGS = 0,
562 unsigned char MEM = 0, unsigned char PORTS = 0>
564 {
565 enum
566 {
567 Caps = CAPS,
568 Flags = FLAGS,
569 Mem = MEM,
570 Ports = PORTS
571 };
572 Demand_t() noexcept : Demand(CAPS, FLAGS, MEM, PORTS) {}
573 };
574
582 template<typename D1, typename D2>
583 struct Demand_union_t : Demand_t<__I::Max<D1::Caps, D2::Caps>::Res,
584 D1::Flags | D2::Flags,
585 __I::Max<D1::Mem, D2::Mem>::Res,
586 __I::Max<D1::Ports, D2::Ports>::Res>
587 {};
588
589 L4_std_type_info_ptr _type;
590 Type_info const *const *_bases;
591 unsigned _num_bases;
592 long _proto;
593
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
600 {
601 if (_proto && _proto == proto)
602 return true;
603
604 if (!proto)
605 return false;
606
607 for (unsigned i = 0; i < _num_bases; ++i)
608 if (base(i)->has_proto(proto))
609 return true;
610
611 return false;
612 }
613};
614
620template<typename T> struct Kobject_typeid
621{
632 typedef typename T::__Kobject_typeid::Demand Demand;
633 typedef typename T::__Iface::iface_type Iface;
634 typedef typename T::__Iface_list Iface_list;
635
640 static Type_info const *id() noexcept { return &T::__Kobject_typeid::_m; }
641
649 static Type_info::Demand demand() noexcept
650 { return T::__Kobject_typeid::Demand(); }
651
652 // to be removed ---------------------------------------
653 // p_dispatch -----------------------------------------------------------
669 template<typename THIS, typename A1, typename A2>
670 static int proto_dispatch(THIS *self, long proto, A1 a1, A2 &a2)
671 { return Typeid::P_dispatch<typename T::__Iface_list>::f(self, proto, a1, a2); }
672 // p_dispatch -----------------------------------------------------------
673 // end: to be removed ---------------------------------------
674};
675
677template<> struct Kobject_typeid<void>
678{
680};
681
690template<typename T>
691inline
692Type_info const *kobject_typeid() noexcept
693{ return Kobject_typeid<T>::id(); }
694
699#define L4____GEN_TI(t...) \
700Type_info const t::__Kobject_typeid::_m = \
701{ \
702 L4_KOBJECT_META_RTTI(Derived), \
703 &t::__Kobject_typeid::_b[0], \
704 sizeof(t::__Kobject_typeid::_b) / sizeof(t::__Kobject_typeid::_b[0]), \
705 PROTO \
706}
707
712#define L4____GEN_TI_MEMBERS(BASE_DEMAND...) \
713private: \
714 template< typename T > friend struct Kobject_typeid; \
715protected: \
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; \
720 }; \
721public: \
722 static long const Protocol = PROTO; \
723 typedef L4::Typeid::Rights<Class> Rights;
724
753template<
754 typename Derived,
755 typename Base,
756 long PROTO = PROTO_ANY,
757 typename S_DEMAND = Type_info::Demand_t<>
758>
759class Kobject_t : public Base
760{
761protected:
763 typedef Derived Class;
765 typedef Typeid::Iface<PROTO, Derived> __Iface;
767 typedef Typeid::Merge_list<
768 Typeid::Iface_list<__Iface>, typename Base::__Iface_list
770
772 static void __check_protocols__() noexcept
773 {
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");
776 }
777
779 L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
780
781 // Generate the remaining type information
782 L4____GEN_TI_MEMBERS(typename Base::__Kobject_typeid::Demand)
783};
784
785
787template< typename Derived, typename Base, long PROTO, typename S_DEMAND>
788Type_info const *const
790 __Kobject_typeid::_b[] = { &Base::__Kobject_typeid::_m };
792
797template< typename Derived, typename Base, long PROTO, typename S_DEMAND>
799
800
830template<
831 typename Derived,
832 typename Base1,
833 typename Base2,
834 long PROTO = PROTO_ANY,
835 typename S_DEMAND = Type_info::Demand_t<>
836>
837class Kobject_2t : public Base1, public Base2
838{
839protected:
841 typedef Derived Class;
843 typedef Typeid::Iface<PROTO, Derived> __Iface;
845 typedef Typeid::Merge_list<
846 Typeid::Iface_list<__Iface>,
847 Typeid::Merge_list<
848 typename Base1::__Iface_list,
849 typename Base2::__Iface_list
850 >
852
854 static void __check_protocols__() noexcept
855 {
856 typedef typename Base1::__Iface_list Base1_proto_list;
857 typedef typename Base2::__Iface_list Base2_proto_list;
858
859 typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
860 typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
861 static_assert(!Base1_conflict::value, "ambiguous protocol ID, also in Base1");
862 static_assert(!Base2_conflict::value, "ambiguous protocol ID, also in Base2");
863
864 typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Bases_conflict;
865 static_assert(!Bases_conflict::value, "ambiguous protocol IDs in base classes");
866 }
867
868 // disambiguate cap()
869 l4_cap_idx_t cap() const noexcept
870 { return Base1::cap(); }
871
873 L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
874
875 L4____GEN_TI_MEMBERS(Type_info::Demand_union_t<
876 typename Base1::__Kobject_typeid::Demand,
877 typename Base2::__Kobject_typeid::Demand>
878 )
879
880public:
881 // Provide non-ambiguous conversion to Kobject
882 operator Kobject const & () const noexcept
883 { return *static_cast<Base1 const *>(this); }
884
885 // Provide non-ambiguous access of dec_refcnt()
886 l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
887 noexcept(noexcept(((Base1*)0)->dec_refcnt(diff, utcb)))
888 { return Base1::dec_refcnt(diff, utcb); }
889};
890
891
893template< typename Derived, typename Base1, typename Base2,
894 long PROTO, typename S_DEMAND >
895Type_info const *const
897{
898 &Base1::__Kobject_typeid::_m,
899 &Base2::__Kobject_typeid::_m
900};
902
907template< typename Derived, typename Base1, typename Base2,
908 long PROTO, typename S_DEMAND >
910
911
912
932template<
933 typename Derived,
934 typename Base1,
935 typename Base2,
936 typename Base3,
937 long PROTO = PROTO_ANY,
938 typename S_DEMAND = Type_info::Demand_t<>
939>
940struct Kobject_3t : Base1, Base2, Base3
941{
942protected:
944 typedef Derived Class;
946 typedef Typeid::Iface<PROTO, Derived> __Iface;
948 typedef Typeid::Merge_list<
949 Typeid::Iface_list<__Iface>,
950 Typeid::Merge_list<
951 typename Base1::__Iface_list,
952 Typeid::Merge_list<
953 typename Base2::__Iface_list,
954 typename Base3::__Iface_list
955 >
956 >
958
960 static void __check_protocols__() noexcept
961 {
962 typedef typename Base1::__Iface_list Base1_proto_list;
963 typedef typename Base2::__Iface_list Base2_proto_list;
964 typedef typename Base3::__Iface_list Base3_proto_list;
965
966 typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
967 typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
968 typedef Typeid::Iface_conflict<__Iface, Base3_proto_list> Base3_conflict;
969
970 static_assert(!Base1_conflict::value, "ambiguous protocol ID, also in Base1");
971 static_assert(!Base2_conflict::value, "ambiguous protocol ID, also in Base2");
972 static_assert(!Base3_conflict::value, "ambiguous protocol ID, also in Base3");
973
974 typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Conflict_bases12;
975 typedef Typeid::Conflict<Base1_proto_list, Base3_proto_list> Conflict_bases13;
976 typedef Typeid::Conflict<Base2_proto_list, Base3_proto_list> Conflict_bases23;
977
978 static_assert(!Conflict_bases12::value, "ambiguous protocol IDs in base classes: Base1 and Base2");
979 static_assert(!Conflict_bases13::value, "ambiguous protocol IDs in base classes: Base1 and Base3");
980 static_assert(!Conflict_bases23::value, "ambiguous protocol IDs in base classes: Base2 and Base3");
981 }
982
983 // disambiguate cap()
984 l4_cap_idx_t cap() const noexcept
985 { return Base1::cap(); }
986
988 L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
989
991 typename Base1::__Kobject_typeid::Demand,
992 typename Base2::__Kobject_typeid::Demand>,
993 typename Base3::__Kobject_typeid::Demand>
994 )
995
996public:
997 // Provide non-ambiguous conversion to Kobject
998 operator Kobject const & () const noexcept
999 { return *static_cast<Base1 const *>(this); }
1000
1001 // Provide non-ambiguous access of dec_refcnt()
1002 l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
1003 noexcept(noexcept(((Base1*)0)->dec_refcnt(diff, utcb)))
1004 { return Base1::dec_refcnt(diff, utcb); }
1005};
1006
1007
1009template< typename Derived, typename Base1, typename Base2, typename Base3,
1010 long PROTO, typename S_DEMAND >
1011Type_info const *const
1013{
1014 &Base1::__Kobject_typeid::_m,
1015 &Base2::__Kobject_typeid::_m,
1016 &Base3::__Kobject_typeid::_m
1017};
1019
1024template< typename Derived, typename Base1, typename Base2, typename Base3,
1025 long PROTO, typename S_DEMAND >
1027
1028}
1029
1030#if __cplusplus >= 201103L
1031
1032namespace L4 {
1033
1040template< typename ...T >
1042
1043template<>
1044struct Kobject_demand<> : Type_info::Demand_t<> {};
1045
1046template<typename T>
1047struct Kobject_demand<T> : Kobject_typeid<T>::Demand {};
1048
1049template<typename T1, typename ...T2>
1050struct Kobject_demand<T1, T2...> :
1051 Type_info::Demand_union_t<typename Kobject_typeid<T1>::Demand,
1052 Kobject_demand<T2...> >
1053{};
1054
1055namespace Typeid_xx {
1056
1057 template<typename ...LISTS>
1058 struct Merge_list;
1059
1060 template<typename L>
1061 struct Merge_list<L> : L {};
1062
1063 template<typename L1, typename L2>
1064 struct Merge_list<L1, L2> : Typeid::Merge_list<L1, L2> {};
1065
1066 template<typename L1, typename L2, typename ...LISTS>
1067 struct Merge_list<L1, L2, LISTS...> :
1068 Merge_list<typename Typeid::Merge_list<L1, L2>::type, LISTS...> {};
1069
1070 template< typename I, typename ...LIST >
1071 struct Iface_conflict;
1072
1073 template< typename I >
1074 struct Iface_conflict<I> : Typeid::False {};
1075
1076 template< typename I, typename L, typename ...LIST >
1077 struct Iface_conflict<I, L, LIST...> :
1078 Typeid::Bool<Typeid::Iface_conflict<typename I::type, typename L::type>::value
1079 || Iface_conflict<I, LIST...>::value>
1080 {};
1081
1082 template< typename ...LIST >
1083 struct Conflict;
1084
1085 template< typename L >
1086 struct Conflict<L> : Typeid::False {};
1087
1088 template< typename L1, typename L2, typename ...LIST >
1089 struct Conflict<L1, L2, LIST...> :
1090 Typeid::Bool<Typeid::Conflict<typename L1::type, typename L2::type>::value
1091 || Conflict<L1, LIST...>::value
1092 || Conflict<L2, LIST...>::value>
1093 {};
1094
1095 template< typename T >
1096 struct Is_demand
1097 {
1098 static long test(Type_info::Demand const *);
1099 static char test(...);
1100 enum { value = sizeof(test((T*)0)) == sizeof(long) };
1101 };
1102
1103 template< typename T, typename ... >
1104 struct First : T { typedef T type; };
1105} // Typeid
1106
1112template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
1113struct __Kobject_base : BASES...
1114{
1115protected:
1116 typedef Derived Class;
1117 typedef Typeid::Iface<PROTO, Derived> __Iface;
1118 typedef Typeid_xx::Merge_list<
1119 Typeid::Iface_list<__Iface>,
1120 typename BASES::__Iface_list...
1121 > __Iface_list;
1122
1123 static void __check_protocols__() noexcept
1124 {
1125 typedef Typeid_xx::Iface_conflict<__Iface, typename BASES::__Iface_list...> Conflict;
1126 static_assert(!Conflict::value, "ambiguous protocol ID, protocol also used in base class");
1127
1128 typedef Typeid_xx::Conflict<typename BASES::__Iface_list...> Base_conflict;
1129 static_assert(!Base_conflict::value, "ambiguous protocol IDs in base classes");
1130 }
1131
1132 // disambiguate cap()
1133 l4_cap_idx_t cap() const noexcept
1134 { return Typeid_xx::First<BASES...>::type::cap(); }
1135
1136 L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
1137
1138 L4____GEN_TI_MEMBERS(Kobject_demand<BASES...>)
1139
1140private:
1141 // This function returns the first base class (used below)
1142 template<typename B1, typename ...> struct Base1 { typedef B1 type; };
1143
1144public:
1145 // Provide non-ambiguous conversion to Kobject
1146 operator Kobject const & () const noexcept
1147 { return *static_cast<typename Base1<BASES...>::type const *>(this); }
1148
1149 // Provide non-ambiguous access of dec_refcnt()
1150 l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
1151 noexcept(noexcept(((typename Base1<BASES...>::type *)0)->dec_refcnt(diff, utcb)))
1152 { return Base1<BASES...>::type::dec_refcnt(diff, utcb); }
1153};
1154
1156template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
1157Type_info const *const
1158__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>::__Kobject_typeid::_b[] =
1159{
1160 (&BASES::__Kobject_typeid::_m)...
1161};
1163
1164template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
1165L4____GEN_TI(__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>);
1166
1167
1168// Test if the there is a Demand argument to Kobject_x
1169template< typename Derived, long PROTO, bool HAS_DEMAND, typename DEMAND, typename ...ARGS >
1170struct __Kobject_x_proto;
1171
1172// YES: pass it to __Kobject_base
1173template< typename Derived, long PROTO, typename DEMAND, typename ...BASES>
1174struct __Kobject_x_proto<Derived, PROTO, true, DEMAND, BASES...> :
1175 __Kobject_base<Derived, PROTO, DEMAND, BASES...> {};
1176
1177// NO: pass it empty Type_info::Demand_t
1178template< typename Derived, long PROTO, typename B1, typename ...BASES>
1179struct __Kobject_x_proto<Derived, PROTO, false, B1, BASES...> :
1180 __Kobject_base<Derived, PROTO, Type_info::Demand_t<>, B1, BASES...> {};
1181
1189template< long P = PROTO_EMPTY >
1190struct Proto_t {};
1191
1205template< typename Derived, typename ...ARGS >
1207
1208template< typename Derived, typename A, typename ...ARGS >
1209struct Kobject_x<Derived, A, ARGS...> :
1210 __Kobject_x_proto<Derived, PROTO_ANY, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1211{};
1212
1213template< typename Derived, long PROTO, typename A, typename ...ARGS >
1214struct Kobject_x<Derived, Proto_t<PROTO>, A, ARGS...> :
1215 __Kobject_x_proto<Derived, PROTO, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1216{};
1217
1218}
1219#endif
1220
1221#undef L4____GEN_TI
1222#undef L4____GEN_TI_MEMBERS
1223
C++ interface for capabilities.
Definition capability.h:222
Helper class to create an L4Re interface class that is derived from two base classes (see L4::Kobject...
Definition __typeinfo.h:838
Derived Class
The target interface type (inheriting from Kobject_t)
Definition __typeinfo.h:841
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
Definition __typeinfo.h:873
static void __check_protocols__() noexcept
Helper to check for protocol conflicts.
Definition __typeinfo.h:854
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition __typeinfo.h:843
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:851
Helper class to create an L4Re interface class that is derived from a single base class.
Definition __typeinfo.h:760
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition __typeinfo.h:765
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
Definition __typeinfo.h:779
static void __check_protocols__() noexcept
Helper to check for protocol conflicts.
Definition __typeinfo.h:772
Derived Class
The target interface type (inheriting from Kobject_t)
Definition __typeinfo.h:763
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:769
Base class for all kinds of kernel objects and remote objects, referenced by capabilities.
Definition kobject:47
Data type for expressing the needed receive buffers at the server-side of an interface.
Definition __typeinfo.h:517
unsigned char mem
number of memory receive buffers.
Definition __typeinfo.h:526
Demand(unsigned char caps=0, unsigned char flags=0, unsigned char mem=0, unsigned char ports=0) noexcept
Make Demand object.
Definition __typeinfo.h:537
unsigned char flags
flags, such as the need for timeouts (TBD).
Definition __typeinfo.h:525
bool no_demand() const noexcept
Definition __typeinfo.h:542
unsigned char caps
number of capability receive buffers.
Definition __typeinfo.h:524
unsigned char ports
number of IO-port receive buffers.
Definition __typeinfo.h:527
Template for defining typical Flags bitmaps.
Definition types:64
signed long l4_mword_t
Signed machine word.
Definition l4int.h:48
unsigned long l4_cap_idx_t
Capability selector type.
Definition types.h:358
@ L4_EBADPROTO
Unsupported protocol.
Definition err.h:61
Type_info const * kobject_typeid() noexcept
Get the L4::Type_info for the L4Re interface given in T.
Definition __typeinfo.h:692
@ L4_PROTO_META
Meta information protocol.
Definition types.h:73
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition utcb.h:67
l4_utcb_t * l4_utcb(void) L4_NOTHROW L4_PURE
Get the UTCB address.
Definition utcb.h:340
#define L4_EXPORT
Attribute to mark functions, variables, and data types as being exported from a library.
Definition compiler.h:221
L4 basic type helpers for C++.
Definition types:31
L4 low-level kernel interface.
int Opcode
Data type for RPC opcodes.
Definition __typeinfo.h:47
@ PROTO_EMPTY
Empty protocol for empty APIs.
Definition __typeinfo.h:60
@ PROTO_ANY
Default protocol used by Kobject_t and Kobject_x.
Definition __typeinfo.h:58
Helper class to create an L4Re interface class that is derived from three base classes (see L4::Kobje...
Definition __typeinfo.h:941
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:957
Derived Class
The target interface type (inheriting from Kobject_t)
Definition __typeinfo.h:944
static void __check_protocols__() noexcept
Helper to check for protocol conflicts.
Definition __typeinfo.h:960
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition __typeinfo.h:946
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
Definition __typeinfo.h:988
Get the combined server-side resource requirements for all type T...
Meta object for handling access to type information of Kobjects.
Definition __typeinfo.h:621
static Type_info const * id() noexcept
Get a pointer to teh Kobject type information of T.
Definition __typeinfo.h:640
static int proto_dispatch(THIS *self, long proto, A1 a1, A2 &a2)
Protocol based server-side dispatch function.
Definition __typeinfo.h:670
T::__Kobject_typeid::Demand Demand
Data type expressing the static demand of receive buffers in a server.
Definition __typeinfo.h:632
static Type_info::Demand demand() noexcept
Get the receive-buffer demand for the server providing the interface T.
Definition __typeinfo.h:649
Generic Kobject inheritance template.
Data type for defining protocol numbers.
Template type statically describing demand of receive buffers.
Definition __typeinfo.h:564
Template type statically describing the combination of two Demand object.
Definition __typeinfo.h:587
Dynamic Type Information for L4Re Interfaces.
Definition __typeinfo.h:510
Internal end-of-list marker.
Definition __typeinfo.h:328
R rpc
The RPC type L4::Ipc::Msg::Rpc_call or L4::Ipc::Msg::Rpc_inline_call.
Definition __typeinfo.h:386
_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:388
OPCODE opcode_type
The data type for the opcode.
Definition __typeinfo.h:384
Empty list of RPCs.
Definition __typeinfo.h:375
Use for protocol based dispatch stage.
Definition __typeinfo.h:318
RPCs list for passing raw incoming IPC to the server object.
Definition __typeinfo.h:423
List of RPCs of an interface using a single operation without an opcode.
Definition __typeinfo.h:464
List of RPCs of an interface using a special opcode type.
Definition __typeinfo.h:450
List of RPCs typically used for kernel interfaces.
Definition __typeinfo.h:475
Standard list of RPCs of an interface.
Definition __typeinfo.h:438
Boolean meta type.
Definition types:301
Bool< V > type
The meta type itself.
Definition types:302
False meta value.
Definition types:308
True meta value.
Definition types:312
Message tag data structure.
Definition types.h:163