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,
311 Bool<I::Proto == static_cast<long>(L4_PROTO_META)>());
312
313 return _P_dispatch<typename LIST::type>::f(self, proto, a1, a2);
314 }
315 };
316
318 template<typename LIST>
319 struct P_dispatch : _P_dispatch<typename LIST::type> {};
320 // end: p_dispatch -------------------------------------------------------
321 // end: to be removed ---------------------------------------
322
323 template<typename RPC> struct Default_op;
324
325 namespace Detail {
326
328 struct Rpcs_end
329 {
330 typedef void opcode_type;
331 typedef Rpcs_end rpc;
332 typedef Rpcs_end type;
333 };
334
336 template<typename O1, typename O2, typename RPCS>
337 struct _Rpc : _Rpc<typename RPCS::next::rpc, O2, typename RPCS::next>::type {};
339
340 template<typename O1, typename O2>
341 struct _Rpc<O1, O2, Rpcs_end> {};
342
343 template<typename OP, typename RPCS>
344 struct _Rpc<OP, OP, RPCS> : RPCS
345 {
346 typedef _Rpc type;
347 };
348
349 template<typename OP, typename RPCS>
350 struct Rpc : _Rpc<typename RPCS::rpc, OP, RPCS> {};
351
352 template<typename T, unsigned CODE>
353 struct _Get_opcode
354 {
355 template<bool, typename> struct Invalid_opcode {};
356 template<typename X> struct Invalid_opcode<true, X>;
357
358 private:
359 template<typename U, U> struct _chk;
360 template<typename U> static long _opc(_chk<int, U::Opcode> *);
361 template<typename U> static char _opc(...);
362
363 template<unsigned SZ, typename U>
364 struct _Opc { enum { value = CODE }; };
365
366 template<typename U>
367 struct _Opc<sizeof(long), U> { enum { value = U::Opcode }; };
368
369 public:
370 enum { value = _Opc<sizeof(_opc<T>(0)), T>::value };
371 Invalid_opcode<(value < CODE), T> invalid_opcode;
372 };
373
375 template<typename OPCODE, unsigned O, typename ...X>
376 struct _Rpcs : Rpcs_end {};
377
379 template<typename OPCODE, unsigned O, typename R, typename ...X>
380 struct _Rpcs<OPCODE, O, R, X...>
381 {
383 typedef _Rpcs type;
385 typedef OPCODE opcode_type;
387 typedef R rpc;
389 typedef typename _Rpcs<OPCODE, _Get_opcode<R, O>::value + 1, X...>::type next;
391 enum { Opcode = _Get_opcode<R, O>::value };
393 template<typename Y> struct Rpc : Typeid::Detail::Rpc<Y, _Rpcs> {};
394 };
395
396 template<typename OPCODE, unsigned O, typename R>
397 struct _Rpcs<OPCODE, O, Default_op<R> >
398 {
400 typedef _Rpcs type;
402 typedef void opcode_type;
404 typedef R rpc;
406 typedef Rpcs_end next;
408 enum { Opcode = -99 };
410 template<typename Y> struct Rpc : Typeid::Detail::Rpc<Y, _Rpcs> {};
411 };
412
413 } // namespace Detail
414
422 template<typename CLASS>
423 struct Raw_ipc
424 {
425 typedef Raw_ipc type;
426 typedef Detail::Rpcs_end next;
427 typedef void opcode_type;
428 };
429
438 template<typename ...RPCS>
439 struct Rpcs : Detail::_Rpcs<L4::Opcode, 0, RPCS...> {};
440
449 template<typename OPCODE_TYPE>
451 {
455 template<typename ...RPCS>
456 struct F : Detail::_Rpcs<OPCODE_TYPE, 0, RPCS...> {};
457 };
458
464 template<typename OPERATION>
465 struct Rpc_nocode : Detail::_Rpcs<void, 0, OPERATION> {};
466
475 template<typename ...ARG>
476 struct Rpcs_sys : Detail::_Rpcs<l4_umword_t, 0, ARG...> {};
477
478 template<typename CLASS>
479 struct Rights
480 {
481 unsigned rights;
482 Rights(unsigned rights) noexcept : rights(rights) {}
483 unsigned operator & (unsigned rhs) const noexcept { return rights & rhs; }
484 };
485
486} // namespace Typeid
487
511{
518 {
519 private:
521 static unsigned char max(unsigned char a, unsigned char b) noexcept
522 { return a > b ? a : b; }
523
524 public:
525 unsigned char caps;
526 unsigned char flags;
527 unsigned char mem;
528 unsigned char ports;
529
537 explicit
538 Demand(unsigned char caps = 0, unsigned char flags = 0,
539 unsigned char mem = 0, unsigned char ports = 0) noexcept
540 : caps(caps), flags(flags), mem(mem), ports(ports) {}
541
543 bool no_demand() const noexcept
544 { return caps == 0 && mem == 0 && ports == 0 && flags == 0; }
545
547 Demand operator | (Demand const &rhs) const noexcept
548 {
549 return Demand(max(caps, rhs.caps), flags | rhs.flags,
550 max(mem, rhs.mem), max(ports, rhs.ports));
551 }
552 };
553
562 template<unsigned char CAPS = 0, unsigned char FLAGS = 0,
563 unsigned char MEM = 0, unsigned char PORTS = 0>
565 {
566 enum
567 {
568 Caps = CAPS,
569 Flags = FLAGS,
570 Mem = MEM,
571 Ports = PORTS
572 };
573 Demand_t() noexcept : Demand(CAPS, FLAGS, MEM, PORTS) {}
574 };
575
583 template<typename D1, typename D2>
584 struct Demand_union_t : Demand_t<__I::Max<D1::Caps, D2::Caps>::Res,
585 D1::Flags | D2::Flags,
586 __I::Max<D1::Mem, D2::Mem>::Res,
587 __I::Max<D1::Ports, D2::Ports>::Res>
588 {};
589
590 L4_std_type_info_ptr _type;
591 Type_info const *const *_bases;
592 unsigned _num_bases;
593 long _proto;
594
595 L4_std_type_info_ptr type() const noexcept { return _type; }
596 Type_info const *base(unsigned idx) const noexcept { return _bases[idx]; }
597 unsigned num_bases() const noexcept { return _num_bases; }
598 long proto() const noexcept { return _proto; }
599 char const *name() const noexcept { return L4_kobject_type_name(type()); }
600 bool has_proto(long proto) const noexcept
601 {
602 if (_proto && _proto == proto)
603 return true;
604
605 if (!proto)
606 return false;
607
608 for (unsigned i = 0; i < _num_bases; ++i)
609 if (base(i)->has_proto(proto))
610 return true;
611
612 return false;
613 }
614};
615
621template<typename T> struct Kobject_typeid
622{
633 typedef typename T::__Kobject_typeid::Demand Demand;
634 typedef typename T::__Iface::iface_type Iface;
635 typedef typename T::__Iface_list Iface_list;
636
641 static Type_info const *id() noexcept { return &T::__Kobject_typeid::_m; }
642
650 static Type_info::Demand demand() noexcept
651 { return T::__Kobject_typeid::Demand(); }
652
653 // to be removed ---------------------------------------
654 // p_dispatch -----------------------------------------------------------
670 template<typename THIS, typename A1, typename A2>
671 static int proto_dispatch(THIS *self, long proto, A1 a1, A2 &a2)
672 { return Typeid::P_dispatch<typename T::__Iface_list>::f(self, proto, a1, a2); }
673 // p_dispatch -----------------------------------------------------------
674 // end: to be removed ---------------------------------------
675};
676
678template<> struct Kobject_typeid<void>
679{
681};
682
691template<typename T>
692inline
693Type_info const *kobject_typeid() noexcept
694{ return Kobject_typeid<T>::id(); }
695
700#define L4____GEN_TI(t...) \
701Type_info const t::__Kobject_typeid::_m = \
702{ \
703 L4_KOBJECT_META_RTTI(Derived), \
704 &t::__Kobject_typeid::_b[0], \
705 sizeof(t::__Kobject_typeid::_b) / sizeof(t::__Kobject_typeid::_b[0]), \
706 PROTO \
707}
708
713#define L4____GEN_TI_MEMBERS(BASE_DEMAND...) \
714private: \
715 template< typename T > friend struct Kobject_typeid; \
716protected: \
717 struct __Kobject_typeid { \
718 typedef Type_info::Demand_union_t<S_DEMAND, BASE_DEMAND> Demand; \
719 static Type_info const *const _b[]; \
720 static Type_info const _m; \
721 }; \
722public: \
723 static long const Protocol = PROTO; \
724 typedef L4::Typeid::Rights<Class> Rights;
725
754template<
755 typename Derived,
756 typename Base,
757 long PROTO = PROTO_ANY,
758 typename S_DEMAND = Type_info::Demand_t<>
759>
760class Kobject_t : public Base
761{
762protected:
764 typedef Derived Class;
766 typedef Typeid::Iface<PROTO, Derived> __Iface;
768 typedef Typeid::Merge_list<
769 Typeid::Iface_list<__Iface>, typename Base::__Iface_list
771
773 static void __check_protocols__() noexcept
774 {
775 typedef Typeid::Iface_conflict<__Iface, typename Base::__Iface_list> Base_conflict;
776 static_assert(!Base_conflict::value, "ambiguous protocol ID: protocol also used by Base");
777 }
778
780 L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
781
782 // Generate the remaining type information
783 L4____GEN_TI_MEMBERS(typename Base::__Kobject_typeid::Demand)
784};
785
786
788template< typename Derived, typename Base, long PROTO, typename S_DEMAND>
789Type_info const *const
791 __Kobject_typeid::_b[] = { &Base::__Kobject_typeid::_m };
793
798template< typename Derived, typename Base, long PROTO, typename S_DEMAND>
800
801
831template<
832 typename Derived,
833 typename Base1,
834 typename Base2,
835 long PROTO = PROTO_ANY,
836 typename S_DEMAND = Type_info::Demand_t<>
837>
838class Kobject_2t : public Base1, public Base2
839{
840protected:
842 typedef Derived Class;
844 typedef Typeid::Iface<PROTO, Derived> __Iface;
846 typedef Typeid::Merge_list<
847 Typeid::Iface_list<__Iface>,
848 Typeid::Merge_list<
849 typename Base1::__Iface_list,
850 typename Base2::__Iface_list
851 >
853
855 static void __check_protocols__() noexcept
856 {
857 typedef typename Base1::__Iface_list Base1_proto_list;
858 typedef typename Base2::__Iface_list Base2_proto_list;
859
860 typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
861 typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
862 static_assert(!Base1_conflict::value, "ambiguous protocol ID, also in Base1");
863 static_assert(!Base2_conflict::value, "ambiguous protocol ID, also in Base2");
864
865 typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Bases_conflict;
866 static_assert(!Bases_conflict::value, "ambiguous protocol IDs in base classes");
867 }
868
869 // disambiguate cap()
870 l4_cap_idx_t cap() const noexcept
871 { return Base1::cap(); }
872
874 L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
875
876 L4____GEN_TI_MEMBERS(Type_info::Demand_union_t<
877 typename Base1::__Kobject_typeid::Demand,
878 typename Base2::__Kobject_typeid::Demand>
879 )
880
881public:
882 // Provide non-ambiguous conversion to Kobject
883 operator Kobject const & () const noexcept
884 { return *static_cast<Base1 const *>(this); }
885
886 // Provide non-ambiguous access of dec_refcnt()
887 l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
888 noexcept(noexcept(static_cast<Base1*>(nullptr)->dec_refcnt(diff, utcb)))
889 { return Base1::dec_refcnt(diff, utcb); }
890};
891
892
894template< typename Derived, typename Base1, typename Base2,
895 long PROTO, typename S_DEMAND >
896Type_info const *const
898{
899 &Base1::__Kobject_typeid::_m,
900 &Base2::__Kobject_typeid::_m
901};
903
908template< typename Derived, typename Base1, typename Base2,
909 long PROTO, typename S_DEMAND >
911
912
913
933template<
934 typename Derived,
935 typename Base1,
936 typename Base2,
937 typename Base3,
938 long PROTO = PROTO_ANY,
939 typename S_DEMAND = Type_info::Demand_t<>
940>
941struct Kobject_3t : Base1, Base2, Base3
942{
943protected:
945 typedef Derived Class;
947 typedef Typeid::Iface<PROTO, Derived> __Iface;
949 typedef Typeid::Merge_list<
950 Typeid::Iface_list<__Iface>,
951 Typeid::Merge_list<
952 typename Base1::__Iface_list,
953 Typeid::Merge_list<
954 typename Base2::__Iface_list,
955 typename Base3::__Iface_list
956 >
957 >
959
961 static void __check_protocols__() noexcept
962 {
963 typedef typename Base1::__Iface_list Base1_proto_list;
964 typedef typename Base2::__Iface_list Base2_proto_list;
965 typedef typename Base3::__Iface_list Base3_proto_list;
966
967 typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
968 typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
969 typedef Typeid::Iface_conflict<__Iface, Base3_proto_list> Base3_conflict;
970
971 static_assert(!Base1_conflict::value, "ambiguous protocol ID, also in Base1");
972 static_assert(!Base2_conflict::value, "ambiguous protocol ID, also in Base2");
973 static_assert(!Base3_conflict::value, "ambiguous protocol ID, also in Base3");
974
975 typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Conflict_bases12;
976 typedef Typeid::Conflict<Base1_proto_list, Base3_proto_list> Conflict_bases13;
977 typedef Typeid::Conflict<Base2_proto_list, Base3_proto_list> Conflict_bases23;
978
979 static_assert(!Conflict_bases12::value, "ambiguous protocol IDs in base classes: Base1 and Base2");
980 static_assert(!Conflict_bases13::value, "ambiguous protocol IDs in base classes: Base1 and Base3");
981 static_assert(!Conflict_bases23::value, "ambiguous protocol IDs in base classes: Base2 and Base3");
982 }
983
984 // disambiguate cap()
985 l4_cap_idx_t cap() const noexcept
986 { return Base1::cap(); }
987
989 L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
990
992 typename Base1::__Kobject_typeid::Demand,
993 typename Base2::__Kobject_typeid::Demand>,
994 typename Base3::__Kobject_typeid::Demand>
995 )
996
997public:
998 // Provide non-ambiguous conversion to Kobject
999 operator Kobject const & () const noexcept
1000 { return *static_cast<Base1 const *>(this); }
1001
1002 // Provide non-ambiguous access of dec_refcnt()
1003 l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
1004 noexcept(noexcept(static_cast<Base1*>(nullptr)->dec_refcnt(diff, utcb)))
1005 { return Base1::dec_refcnt(diff, utcb); }
1006};
1007
1008
1010template< typename Derived, typename Base1, typename Base2, typename Base3,
1011 long PROTO, typename S_DEMAND >
1012Type_info const *const
1014{
1015 &Base1::__Kobject_typeid::_m,
1016 &Base2::__Kobject_typeid::_m,
1017 &Base3::__Kobject_typeid::_m
1018};
1020
1025template< typename Derived, typename Base1, typename Base2, typename Base3,
1026 long PROTO, typename S_DEMAND >
1028
1029}
1030
1031#if __cplusplus >= 201103L
1032
1033namespace L4 {
1034
1041template< typename ...T >
1043
1044template<>
1045struct Kobject_demand<> : Type_info::Demand_t<> {};
1046
1047template<typename T>
1048struct Kobject_demand<T> : Kobject_typeid<T>::Demand {};
1049
1050template<typename T1, typename ...T2>
1051struct Kobject_demand<T1, T2...> :
1052 Type_info::Demand_union_t<typename Kobject_typeid<T1>::Demand,
1053 Kobject_demand<T2...> >
1054{};
1055
1056namespace Typeid_xx {
1057
1058 template<typename ...LISTS>
1059 struct Merge_list;
1060
1061 template<typename L>
1062 struct Merge_list<L> : L {};
1063
1064 template<typename L1, typename L2>
1065 struct Merge_list<L1, L2> : Typeid::Merge_list<L1, L2> {};
1066
1067 template<typename L1, typename L2, typename ...LISTS>
1068 struct Merge_list<L1, L2, LISTS...> :
1069 Merge_list<typename Typeid::Merge_list<L1, L2>::type, LISTS...> {};
1070
1071 template< typename I, typename ...LIST >
1072 struct Iface_conflict;
1073
1074 template< typename I >
1075 struct Iface_conflict<I> : Typeid::False {};
1076
1077 template< typename I, typename L, typename ...LIST >
1078 struct Iface_conflict<I, L, LIST...> :
1079 Typeid::Bool<Typeid::Iface_conflict<typename I::type, typename L::type>::value
1080 || Iface_conflict<I, LIST...>::value>
1081 {};
1082
1083 template< typename ...LIST >
1084 struct Conflict;
1085
1086 template< typename L >
1087 struct Conflict<L> : Typeid::False {};
1088
1089 template< typename L1, typename L2, typename ...LIST >
1090 struct Conflict<L1, L2, LIST...> :
1091 Typeid::Bool<Typeid::Conflict<typename L1::type, typename L2::type>::value
1092 || Conflict<L1, LIST...>::value
1093 || Conflict<L2, LIST...>::value>
1094 {};
1095
1096 template< typename T >
1097 struct Is_demand
1098 {
1099 static long test(Type_info::Demand const *);
1100 static char test(...);
1101 enum { value = sizeof(test(static_cast<T*>(nullptr))) == sizeof(long) };
1102 };
1103
1104 template< typename T, typename ... >
1105 struct First : T { typedef T type; };
1106} // Typeid
1107
1113template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
1114struct __Kobject_base : BASES...
1115{
1116protected:
1117 typedef Derived Class;
1118 typedef Typeid::Iface<PROTO, Derived> __Iface;
1119 typedef Typeid_xx::Merge_list<
1120 Typeid::Iface_list<__Iface>,
1121 typename BASES::__Iface_list...
1122 > __Iface_list;
1123
1124 static void __check_protocols__() noexcept
1125 {
1126 typedef Typeid_xx::Iface_conflict<__Iface, typename BASES::__Iface_list...> Conflict;
1127 static_assert(!Conflict::value, "ambiguous protocol ID, protocol also used in base class");
1128
1129 typedef Typeid_xx::Conflict<typename BASES::__Iface_list...> Base_conflict;
1130 static_assert(!Base_conflict::value, "ambiguous protocol IDs in base classes");
1131 }
1132
1133 // disambiguate cap()
1134 l4_cap_idx_t cap() const noexcept
1135 { return Typeid_xx::First<BASES...>::type::cap(); }
1136
1137 L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
1138
1139 L4____GEN_TI_MEMBERS(Kobject_demand<BASES...>)
1140
1141private:
1142 // This function returns the first base class (used below)
1143 template<typename B1, typename ...> struct Base1 { typedef B1 type; };
1144
1145public:
1146 // Provide non-ambiguous conversion to Kobject
1147 operator Kobject const & () const noexcept
1148 { return *static_cast<typename Base1<BASES...>::type const *>(this); }
1149
1150 // Provide non-ambiguous access of dec_refcnt()
1151 l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
1152 noexcept(noexcept(static_cast<typename Base1<BASES...>::type *>(nullptr)
1153 ->dec_refcnt(diff, utcb)))
1154 { return Base1<BASES...>::type::dec_refcnt(diff, utcb); }
1155};
1156
1158template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
1159Type_info const *const
1160__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>::__Kobject_typeid::_b[] =
1161{
1162 (&BASES::__Kobject_typeid::_m)...
1163};
1165
1166template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
1167L4____GEN_TI(__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>);
1168
1169
1170// Test if the there is a Demand argument to Kobject_x
1171template< typename Derived, long PROTO, bool HAS_DEMAND, typename DEMAND, typename ...ARGS >
1172struct __Kobject_x_proto;
1173
1174// YES: pass it to __Kobject_base
1175template< typename Derived, long PROTO, typename DEMAND, typename ...BASES>
1176struct __Kobject_x_proto<Derived, PROTO, true, DEMAND, BASES...> :
1177 __Kobject_base<Derived, PROTO, DEMAND, BASES...> {};
1178
1179// NO: pass it empty Type_info::Demand_t
1180template< typename Derived, long PROTO, typename B1, typename ...BASES>
1181struct __Kobject_x_proto<Derived, PROTO, false, B1, BASES...> :
1182 __Kobject_base<Derived, PROTO, Type_info::Demand_t<>, B1, BASES...> {};
1183
1191template< long P = PROTO_EMPTY >
1192struct Proto_t {};
1193
1207template< typename Derived, typename ...ARGS >
1209
1210template< typename Derived, typename A, typename ...ARGS >
1211struct Kobject_x<Derived, A, ARGS...> :
1212 __Kobject_x_proto<Derived, PROTO_ANY, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1213{};
1214
1215template< typename Derived, long PROTO, typename A, typename ...ARGS >
1216struct Kobject_x<Derived, Proto_t<PROTO>, A, ARGS...> :
1217 __Kobject_x_proto<Derived, PROTO, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1218{};
1219
1220}
1221#endif
1222
1223#undef L4____GEN_TI
1224#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:839
Derived Class
The target interface type (inheriting from Kobject_t)
Definition __typeinfo.h:842
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
Definition __typeinfo.h:874
static void __check_protocols__() noexcept
Helper to check for protocol conflicts.
Definition __typeinfo.h:855
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition __typeinfo.h:844
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:852
Helper class to create an L4Re interface class that is derived from a single base class.
Definition __typeinfo.h:761
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition __typeinfo.h:766
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
Definition __typeinfo.h:780
static void __check_protocols__() noexcept
Helper to check for protocol conflicts.
Definition __typeinfo.h:773
Derived Class
The target interface type (inheriting from Kobject_t)
Definition __typeinfo.h:764
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:770
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:518
unsigned char mem
number of memory receive buffers.
Definition __typeinfo.h:527
Demand(unsigned char caps=0, unsigned char flags=0, unsigned char mem=0, unsigned char ports=0) noexcept
Make Demand object.
Definition __typeinfo.h:538
unsigned char flags
flags, such as the need for timeouts (TBD).
Definition __typeinfo.h:526
bool no_demand() const noexcept
Definition __typeinfo.h:543
unsigned char caps
number of capability receive buffers.
Definition __typeinfo.h:525
unsigned char ports
number of IO-port receive buffers.
Definition __typeinfo.h:528
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:359
@ L4_EBADPROTO
Unsupported protocol.
Definition err.h:62
Type_info const * kobject_typeid() noexcept
Get the L4::Type_info for the L4Re interface given in T.
Definition __typeinfo.h:693
@ 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:231
L4 basic type helpers for C++.
Definition types:31
L4 low-level kernel interface.
Definition io_regblock.h:19
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:942
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:958
Derived Class
The target interface type (inheriting from Kobject_t)
Definition __typeinfo.h:945
static void __check_protocols__() noexcept
Helper to check for protocol conflicts.
Definition __typeinfo.h:961
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition __typeinfo.h:947
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
Definition __typeinfo.h:989
Get the combined server-side resource requirements for all type T...
Meta object for handling access to type information of Kobjects.
Definition __typeinfo.h:622
static Type_info const * id() noexcept
Get a pointer to teh Kobject type information of T.
Definition __typeinfo.h:641
static int proto_dispatch(THIS *self, long proto, A1 a1, A2 &a2)
Protocol based server-side dispatch function.
Definition __typeinfo.h:671
T::__Kobject_typeid::Demand Demand
Data type expressing the static demand of receive buffers in a server.
Definition __typeinfo.h:633
static Type_info::Demand demand() noexcept
Get the receive-buffer demand for the server providing the interface T.
Definition __typeinfo.h:650
Generic Kobject inheritance template.
Data type for defining protocol numbers.
Template type statically describing demand of receive buffers.
Definition __typeinfo.h:565
Template type statically describing the combination of two Demand object.
Definition __typeinfo.h:588
Dynamic Type Information for L4Re Interfaces.
Definition __typeinfo.h:511
Internal end-of-list marker.
Definition __typeinfo.h:329
R rpc
The RPC type L4::Ipc::Msg::Rpc_call or L4::Ipc::Msg::Rpc_inline_call.
Definition __typeinfo.h:387
_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:389
OPCODE opcode_type
The data type for the opcode.
Definition __typeinfo.h:385
Empty list of RPCs.
Definition __typeinfo.h:376
Use for protocol based dispatch stage.
Definition __typeinfo.h:319
RPCs list for passing raw incoming IPC to the server object.
Definition __typeinfo.h:424
List of RPCs of an interface using a single operation without an opcode.
Definition __typeinfo.h:465
List of RPCs of an interface using a special opcode type.
Definition __typeinfo.h:451
List of RPCs typically used for kernel interfaces.
Definition __typeinfo.h:476
Standard list of RPCs of an interface.
Definition __typeinfo.h:439
Boolean meta type.
Definition types:300
Bool< V > type
The meta type itself.
Definition types:301
False meta value.
Definition types:307
True meta value.
Definition types:311
Message tag data structure.
Definition types.h:164