L4Re - L4 Runtime Environment
__typeinfo.h
Go to the documentation of this file.
1 
5 /*
6  * Copyright (C) 2015 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)
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)
43  { return 0; }
44 #endif
45 
46 namespace L4 {
47  typedef int Opcode;
48 // internal max helpers
49 namespace __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 
55 enum
56 {
58  PROTO_ANY = 0,
60  PROTO_EMPTY = -19,
61 };
62 
77 namespace 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) { 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)
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 &)
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;
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>
449  struct Rpcs_code
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) : rights(rights) {}
482  unsigned operator & (unsigned rhs) const { return rights & rhs; }
483  };
484 
485 } // namespace Typeid
486 
509 struct L4_EXPORT Type_info
510 {
516  class L4_EXPORT Demand
517  {
518  private:
520  static unsigned char max(unsigned char a, unsigned char b)
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)
539  : caps(caps), flags(flags), mem(mem), ports(ports) {}
540 
542  bool no_demand() const
543  { return caps == 0 && mem == 0 && ports == 0 && flags == 0; }
544 
546  Demand operator | (Demand const &rhs) const
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>
563  struct Demand_t : Demand
564  {
565  enum
566  {
567  Caps = CAPS,
568  Flags = FLAGS,
569  Mem = MEM,
570  Ports = PORTS
571  };
572  Demand_t() : 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 { return _type; }
595  Type_info const *base(unsigned idx) const { return _bases[idx]; }
596  unsigned num_bases() const { return _num_bases; }
597  long proto() const { return _proto; }
598  char const *name() const { return L4_kobject_type_name(type()); }
599  bool has_proto(long proto) const
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 
620 template<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() { return &T::__Kobject_typeid::_m; }
641 
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 
677 template<> struct Kobject_typeid<void>
678 {
680 };
681 
690 template<typename T>
691 inline
693 { return Kobject_typeid<T>::id(); }
694 
699 #define L4____GEN_TI(t...) \
700 Type_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...) \
713 private: \
714  template< typename T > friend struct Kobject_typeid; \
715 protected: \
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  }; \
721 public: \
722  static long const Protocol = PROTO; \
723  typedef L4::Typeid::Rights<Class> Rights;
724 
753 template<
754  typename Derived,
755  typename Base,
756  long PROTO = PROTO_ANY,
757  typename S_DEMAND = Type_info::Demand_t<>
758 >
759 class Kobject_t : public Base
760 {
761 protected:
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__()
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 { 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 
786 template< typename Derived, typename Base, long PROTO, typename S_DEMAND>
787 Type_info const *const
789  __Kobject_typeid::_b[] = { &Base::__Kobject_typeid::_m };
790 
795 template< typename Derived, typename Base, long PROTO, typename S_DEMAND>
797 
798 
828 template<
829  typename Derived,
830  typename Base1,
831  typename Base2,
832  long PROTO = PROTO_ANY,
833  typename S_DEMAND = Type_info::Demand_t<>
834 >
835 class Kobject_2t : public Base1, public Base2
836 {
837 protected:
839  typedef Derived Class;
841  typedef Typeid::Iface<PROTO, Derived> __Iface;
843  typedef Typeid::Merge_list<
844  Typeid::Iface_list<__Iface>,
845  Typeid::Merge_list<
846  typename Base1::__Iface_list,
847  typename Base2::__Iface_list
848  >
850 
852  static void __check_protocols__()
853  {
854  typedef typename Base1::__Iface_list Base1_proto_list;
855  typedef typename Base2::__Iface_list Base2_proto_list;
856 
857  typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
858  typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
859  static_assert(!Base1_conflict::value, "ambiguous protocol ID, also in Base1");
860  static_assert(!Base2_conflict::value, "ambiguous protocol ID, also in Base2");
861 
862  typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Bases_conflict;
863  static_assert(!Bases_conflict::value, "ambiguous protocol IDs in base classes");
864  }
865 
866  // disambiguate cap()
867  l4_cap_idx_t cap() const throw()
868  { return Base1::cap(); }
869 
871  L4::Cap<Class> c() const { return L4::Cap<Class>(this->cap()); }
872 
873  L4____GEN_TI_MEMBERS(Type_info::Demand_union_t<
874  typename Base1::__Kobject_typeid::Demand,
875  typename Base2::__Kobject_typeid::Demand>
876  )
877 
878 public:
879  // Provide non-ambiguous conversion to Kobject
880  operator Kobject const & () const
881  { return *static_cast<Base1 const *>(this); }
882 
883  // Provide non-ambiguous access of dec_refcnt()
884  l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
885  { return Base1::dec_refcnt(diff, utcb); }
886 };
887 
888 
889 template< typename Derived, typename Base1, typename Base2,
890  long PROTO, typename S_DEMAND >
891 Type_info const *const
893 {
894  &Base1::__Kobject_typeid::_m,
895  &Base2::__Kobject_typeid::_m
896 };
897 
902 template< typename Derived, typename Base1, typename Base2,
903  long PROTO, typename S_DEMAND >
905 
906 
907 
927 template<
928  typename Derived,
929  typename Base1,
930  typename Base2,
931  typename Base3,
932  long PROTO = PROTO_ANY,
933  typename S_DEMAND = Type_info::Demand_t<>
934 >
935 struct Kobject_3t : Base1, Base2, Base3
936 {
937 protected:
939  typedef Derived Class;
941  typedef Typeid::Iface<PROTO, Derived> __Iface;
943  typedef Typeid::Merge_list<
944  Typeid::Iface_list<__Iface>,
945  Typeid::Merge_list<
946  typename Base1::__Iface_list,
947  Typeid::Merge_list<
948  typename Base2::__Iface_list,
949  typename Base3::__Iface_list
950  >
951  >
953 
955  static void __check_protocols__()
956  {
957  typedef typename Base1::__Iface_list Base1_proto_list;
958  typedef typename Base2::__Iface_list Base2_proto_list;
959  typedef typename Base3::__Iface_list Base3_proto_list;
960 
961  typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
962  typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
963  typedef Typeid::Iface_conflict<__Iface, Base3_proto_list> Base3_conflict;
964 
965  static_assert(!Base1_conflict::value, "ambiguous protocol ID, also in Base1");
966  static_assert(!Base2_conflict::value, "ambiguous protocol ID, also in Base2");
967  static_assert(!Base3_conflict::value, "ambiguous protocol ID, also in Base3");
968 
969  typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Conflict_bases12;
970  typedef Typeid::Conflict<Base1_proto_list, Base3_proto_list> Conflict_bases13;
971  typedef Typeid::Conflict<Base2_proto_list, Base3_proto_list> Conflict_bases23;
972 
973  static_assert(!Conflict_bases12::value, "ambiguous protocol IDs in base classes: Base1 and Base2");
974  static_assert(!Conflict_bases13::value, "ambiguous protocol IDs in base classes: Base1 and Base3");
975  static_assert(!Conflict_bases23::value, "ambiguous protocol IDs in base classes: Base2 and Base3");
976  }
977 
978  // disambiguate cap()
979  l4_cap_idx_t cap() const throw()
980  { return Base1::cap(); }
981 
983  L4::Cap<Class> c() const { return L4::Cap<Class>(this->cap()); }
984 
986  typename Base1::__Kobject_typeid::Demand,
987  typename Base2::__Kobject_typeid::Demand>,
988  typename Base3::__Kobject_typeid::Demand>
989  )
990 
991 public:
992  // Provide non-ambiguous conversion to Kobject
993  operator Kobject const & () const
994  { return *static_cast<Base1 const *>(this); }
995 
996  // Provide non-ambiguous access of dec_refcnt()
997  l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
998  { return Base1::dec_refcnt(diff, utcb); }
999 };
1000 
1001 
1002 template< typename Derived, typename Base1, typename Base2, typename Base3,
1003  long PROTO, typename S_DEMAND >
1004 Type_info const *const
1006 {
1007  &Base1::__Kobject_typeid::_m,
1008  &Base2::__Kobject_typeid::_m,
1009  &Base3::__Kobject_typeid::_m
1010 };
1011 
1016 template< typename Derived, typename Base1, typename Base2, typename Base3,
1017  long PROTO, typename S_DEMAND >
1019 
1020 }
1021 
1022 #if __cplusplus >= 201103L
1023 
1024 namespace L4 {
1025 
1032 template< typename ...T >
1034 
1035 template<>
1036 struct Kobject_demand<> : Type_info::Demand_t<> {};
1037 
1038 template<typename T>
1039 struct Kobject_demand<T> : Kobject_typeid<T>::Demand {};
1040 
1041 template<typename T1, typename ...T2>
1042 struct Kobject_demand<T1, T2...> :
1043  Type_info::Demand_union_t<typename Kobject_typeid<T1>::Demand,
1044  Kobject_demand<T2...> >
1045 {};
1046 
1047 namespace Typeid_xx {
1048 
1049  template<typename ...LISTS>
1050  struct Merge_list;
1051 
1052  template<typename L>
1053  struct Merge_list<L> : L {};
1054 
1055  template<typename L1, typename L2>
1056  struct Merge_list<L1, L2> : Typeid::Merge_list<L1, L2> {};
1057 
1058  template<typename L1, typename L2, typename ...LISTS>
1059  struct Merge_list<L1, L2, LISTS...> :
1060  Merge_list<typename Typeid::Merge_list<L1, L2>::type, LISTS...> {};
1061 
1062  template< typename I, typename ...LIST >
1063  struct Iface_conflict;
1064 
1065  template< typename I >
1066  struct Iface_conflict<I> : Typeid::False {};
1067 
1068  template< typename I, typename L, typename ...LIST >
1069  struct Iface_conflict<I, L, LIST...> :
1070  Typeid::Bool<Typeid::Iface_conflict<typename I::type, typename L::type>::value
1071  || Iface_conflict<I, LIST...>::value>
1072  {};
1073 
1074  template< typename ...LIST >
1075  struct Conflict;
1076 
1077  template< typename L >
1078  struct Conflict<L> : Typeid::False {};
1079 
1080  template< typename L1, typename L2, typename ...LIST >
1081  struct Conflict<L1, L2, LIST...> :
1082  Typeid::Bool<Typeid::Conflict<typename L1::type, typename L2::type>::value
1083  || Conflict<L1, LIST...>::value
1084  || Conflict<L2, LIST...>::value>
1085  {};
1086 
1087  template< typename T >
1088  struct Is_demand
1089  {
1090  static long test(Type_info::Demand const *);
1091  static char test(...);
1092  enum { value = sizeof(test((T*)0)) == sizeof(long) };
1093  };
1094 
1095  template< typename T, typename ... >
1096  struct First : T { typedef T type; };
1097 } // Typeid
1098 
1104 template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
1105 struct __Kobject_base : BASES...
1106 {
1107 protected:
1108  typedef Derived Class;
1109  typedef Typeid::Iface<PROTO, Derived> __Iface;
1110  typedef Typeid_xx::Merge_list<
1111  Typeid::Iface_list<__Iface>,
1112  typename BASES::__Iface_list...
1113  > __Iface_list;
1114 
1115  static void __check_protocols__()
1116  {
1117  typedef Typeid_xx::Iface_conflict<__Iface, typename BASES::__Iface_list...> Conflict;
1118  static_assert(!Conflict::value, "ambiguous protocol ID, protocol also used in base class");
1119 
1120  typedef Typeid_xx::Conflict<typename BASES::__Iface_list...> Base_conflict;
1121  static_assert(!Base_conflict::value, "ambiguous protocol IDs in base classes");
1122  }
1123 
1124  // disambiguate cap()
1125  l4_cap_idx_t cap() const throw()
1126  { return Typeid_xx::First<BASES...>::type::cap(); }
1127 
1128  L4::Cap<Class> c() const { return L4::Cap<Class>(this->cap()); }
1129 
1130  L4____GEN_TI_MEMBERS(Kobject_demand<BASES...>)
1131 
1132 private:
1133  // This function returns the first base class (used below)
1134  template<typename B1, typename ...> struct Base1 { typedef B1 type; };
1135 
1136 public:
1137  // Provide non-ambiguous conversion to Kobject
1138  operator Kobject const & () const
1139  { return *static_cast<typename Base1<BASES...>::type const *>(this); }
1140 
1141  // Provide non-ambiguous access of dec_refcnt()
1142  l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
1143  { return Base1<BASES...>::type::dec_refcnt(diff, utcb); }
1144 };
1145 
1146 template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
1147 Type_info const *const
1148 __Kobject_base<Derived, PROTO, S_DEMAND, BASES...>::__Kobject_typeid::_b[] =
1149 {
1150  (&BASES::__Kobject_typeid::_m)...
1151 };
1152 
1153 template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
1154 L4____GEN_TI(__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>);
1155 
1156 
1157 // Test if the there is a Demand argument to Kobject_x
1158 template< typename Derived, long PROTO, bool HAS_DEMAND, typename DEMAND, typename ...ARGS >
1159 struct __Kobject_x_proto;
1160 
1161 // YES: pass it to __Kobject_base
1162 template< typename Derived, long PROTO, typename DEMAND, typename ...BASES>
1163 struct __Kobject_x_proto<Derived, PROTO, true, DEMAND, BASES...> :
1164  __Kobject_base<Derived, PROTO, DEMAND, BASES...> {};
1165 
1166 // NO: pass it empty Type_info::Demand_t
1167 template< typename Derived, long PROTO, typename B1, typename ...BASES>
1168 struct __Kobject_x_proto<Derived, PROTO, false, B1, BASES...> :
1169  __Kobject_base<Derived, PROTO, Type_info::Demand_t<>, B1, BASES...> {};
1170 
1178 template< long P = PROTO_EMPTY >
1179 struct Proto_t {};
1180 
1194 template< typename Derived, typename ...ARGS >
1195 struct Kobject_x;
1196 
1197 template< typename Derived, typename A, typename ...ARGS >
1198 struct Kobject_x<Derived, A, ARGS...> :
1199  __Kobject_x_proto<Derived, PROTO_ANY, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1200 {};
1201 
1202 template< typename Derived, long PROTO, typename A, typename ...ARGS >
1203 struct Kobject_x<Derived, Proto_t<PROTO>, A, ARGS...> :
1204  __Kobject_x_proto<Derived, PROTO, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1205 {};
1206 
1207 }
1208 #endif
1209 
1210 #undef L4____GEN_TI
1211 #undef L4____GEN_TI_MEMBERS
1212 
Default protocol used by Kobject_t and Kobject_x.
Definition: __typeinfo.h:58
static Type_info const * id()
Get a pointer to teh Kobject type information of T.
Definition: __typeinfo.h:640
static Type_info::Demand demand()
Get the receive-buffer demand for the server providing the interface T.
Definition: __typeinfo.h:649
Data type for expressing the needed receive buffers at the server-side of an interface.
Definition: __typeinfo.h:516
unsigned char ports
number of IO-port receive buffers.
Definition: __typeinfo.h:527
Type_info const * kobject_typeid()
Get the L4::Type_info for the L4Re interface given in T.
Definition: __typeinfo.h:692
Helper class to create an L4Re interface class that is derived from three base classes (see L4::Kobje...
Definition: __typeinfo.h:935
Template for defining typical Flags bitmaps.
Definition: types:63
Derived Class
The target interface type (inheriting from Kobject_t)
Definition: __typeinfo.h:939
Standard list of RPCs of an interface.
Definition: __typeinfo.h:438
Get the combined server-side resource requirements for all type T...
Definition: __typeinfo.h:1033
Template type statically describing demand of receive buffers.
Definition: __typeinfo.h:563
static void __check_protocols__()
Definition: __typeinfo.h:955
signed long l4_mword_t
Signed machine word.
Definition: l4int.h:49
L4 low-level kernel interface.
Definition: alloc.h:27
static void __check_protocols__()
Definition: __typeinfo.h:852
Template type statically describing the combination of two Demand object.
Definition: __typeinfo.h:583
_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
unsigned long l4_cap_idx_t
L4 Capability selector Type.
Definition: types.h:342
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition: __typeinfo.h:941
L4::Cap< Class > c() const
Get the capability to ourselves.
Definition: __typeinfo.h:983
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition: utcb.h:67
RPCs list for passing raw incoming IPC to the server object.
Definition: __typeinfo.h:422
bool no_demand() const
Definition: __typeinfo.h:542
Use for protocol based dispatch stage.
Definition: __typeinfo.h:318
T1 max(T1 a, T1 b)
Get the maximum of a and b.
Definition: minmax:46
Derived Class
The target interface type (inheriting from Kobject_t)
Definition: __typeinfo.h:839
List of RPCs of an interface using a single operation without an opcode.
Definition: __typeinfo.h:464
R rpc
The RPC type L4::Ipc::Msg::Rpc_call or L4::Ipc::Msg::Rpc_inline_call.
Definition: __typeinfo.h:386
Generic Kobject inheritance template.
Definition: __typeinfo.h:1195
int Opcode
Data type for RPC opcodes.
Definition: __typeinfo.h:47
unsigned char flags
flags, such as the need for timeouts (TBD).
Definition: __typeinfo.h:525
unsigned char caps
number of capability receive buffers.
Definition: __typeinfo.h:524
static void __check_protocols__()
Helper to check for protocol conflicts.
Definition: __typeinfo.h:772
L4::Cap< Class > c() const
Get the capability to ourselves.
Definition: __typeinfo.h:871
List of RPCs typically used for kernel interfaces.
Definition: __typeinfo.h:475
T::__Kobject_typeid::Demand Demand
Data type expressing the static demand of receive buffers in a server.
Definition: __typeinfo.h:632
Base class for all kinds of kernel objects and remote objects, referenced by capabilities.
Definition: kobject:46
_Rpcs type
The list element itself.
Definition: __typeinfo.h:382
List of RPCs of an interface using a special opcode type.
Definition: __typeinfo.h:449
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:952
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition: __typeinfo.h:841
Demand(unsigned char caps=0, unsigned char flags=0, unsigned char mem=0, unsigned char ports=0)
Make Demand object.
Definition: __typeinfo.h:537
Helper class to create an L4Re interface class that is derived from two base classes (see L4::Kobject...
Definition: __typeinfo.h:835
unsigned char mem
number of memory receive buffers.
Definition: __typeinfo.h:526
Dynamic Type Information for L4Re Interfaces.
Definition: __typeinfo.h:509
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
Data type for defining protocol numbers.
Definition: __typeinfo.h:1179
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:849
l4_utcb_t * l4_utcb(void) L4_NOTHROW L4_PURE
Get the UTCB address.
Definition: utcb.h:340
L4 basic type helpers for C++.
Definition: types:31
Empty list of RPCs.
Definition: __typeinfo.h:375
L4::Cap< Class > c() const
Get the capability to ourselves.
Definition: __typeinfo.h:779
True meta value.
Definition: types:177
Empty protocol for empty APIs.
Definition: __typeinfo.h:60
Boolean meta type.
Definition: types:165
Internal end-of-list marker.
Definition: __typeinfo.h:327
Helper class to create an L4Re interface class that is derived from a single base class...
Definition: __typeinfo.h:759
Unsupported protocol.
Definition: err.h:61
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition: __typeinfo.h:765
Meta information protocol.
Definition: types.h:73
C++ interface for capabilities.
Definition: capability.h:13
OPCODE opcode_type
The data type for the opcode.
Definition: __typeinfo.h:384
Message tag data structure.
Definition: types.h:159
Derived Class
The target interface type (inheriting from Kobject_t)
Definition: __typeinfo.h:763
Meta object for handling access to type information of Kobjects.
Definition: __typeinfo.h:620
static int proto_dispatch(THIS *self, long proto, A1 a1, A2 &a2)
Protocol based server-side dispatch function.
Definition: __typeinfo.h:670
False meta value.
Definition: types:173