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) 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 
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) 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;
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) noexcept : rights(rights) {}
482  unsigned operator & (unsigned rhs) const noexcept { 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) 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>
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() 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 
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() 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 
677 template<> struct Kobject_typeid<void>
678 {
680 };
681 
690 template<typename T>
691 inline
692 Type_info const *kobject_typeid() noexcept
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__() 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 
786 template< typename Derived, typename Base, long PROTO, typename S_DEMAND>
787 Type_info const *const
788 Kobject_t<Derived, Base, PROTO, S_DEMAND>::
789  __Kobject_typeid::_b[] = { &Base::__Kobject_typeid::_m };
790 
795 template< typename Derived, typename Base, long PROTO, typename S_DEMAND>
796 L4____GEN_TI(Kobject_t<Derived, Base, PROTO, 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__() noexcept
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 noexcept
868  { return Base1::cap(); }
869 
871  L4::Cap<Class> c() const noexcept { 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 noexcept
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  noexcept(noexcept(((Base1*)0)->dec_refcnt(diff, utcb)))
886  { return Base1::dec_refcnt(diff, utcb); }
887 };
888 
889 
890 template< typename Derived, typename Base1, typename Base2,
891  long PROTO, typename S_DEMAND >
892 Type_info const *const
893 Kobject_2t<Derived, Base1, Base2, PROTO, S_DEMAND>::__Kobject_typeid::_b[] =
894 {
895  &Base1::__Kobject_typeid::_m,
896  &Base2::__Kobject_typeid::_m
897 };
898 
903 template< typename Derived, typename Base1, typename Base2,
904  long PROTO, typename S_DEMAND >
905 L4____GEN_TI(Kobject_2t<Derived, Base1, Base2, PROTO, S_DEMAND>);
906 
907 
908 
928 template<
929  typename Derived,
930  typename Base1,
931  typename Base2,
932  typename Base3,
933  long PROTO = PROTO_ANY,
934  typename S_DEMAND = Type_info::Demand_t<>
935 >
936 struct Kobject_3t : Base1, Base2, Base3
937 {
938 protected:
940  typedef Derived Class;
942  typedef Typeid::Iface<PROTO, Derived> __Iface;
944  typedef Typeid::Merge_list<
945  Typeid::Iface_list<__Iface>,
946  Typeid::Merge_list<
947  typename Base1::__Iface_list,
948  Typeid::Merge_list<
949  typename Base2::__Iface_list,
950  typename Base3::__Iface_list
951  >
952  >
954 
956  static void __check_protocols__() noexcept
957  {
958  typedef typename Base1::__Iface_list Base1_proto_list;
959  typedef typename Base2::__Iface_list Base2_proto_list;
960  typedef typename Base3::__Iface_list Base3_proto_list;
961 
962  typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
963  typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
964  typedef Typeid::Iface_conflict<__Iface, Base3_proto_list> Base3_conflict;
965 
966  static_assert(!Base1_conflict::value, "ambiguous protocol ID, also in Base1");
967  static_assert(!Base2_conflict::value, "ambiguous protocol ID, also in Base2");
968  static_assert(!Base3_conflict::value, "ambiguous protocol ID, also in Base3");
969 
970  typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Conflict_bases12;
971  typedef Typeid::Conflict<Base1_proto_list, Base3_proto_list> Conflict_bases13;
972  typedef Typeid::Conflict<Base2_proto_list, Base3_proto_list> Conflict_bases23;
973 
974  static_assert(!Conflict_bases12::value, "ambiguous protocol IDs in base classes: Base1 and Base2");
975  static_assert(!Conflict_bases13::value, "ambiguous protocol IDs in base classes: Base1 and Base3");
976  static_assert(!Conflict_bases23::value, "ambiguous protocol IDs in base classes: Base2 and Base3");
977  }
978 
979  // disambiguate cap()
980  l4_cap_idx_t cap() const noexcept
981  { return Base1::cap(); }
982 
984  L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
985 
987  typename Base1::__Kobject_typeid::Demand,
988  typename Base2::__Kobject_typeid::Demand>,
989  typename Base3::__Kobject_typeid::Demand>
990  )
991 
992 public:
993  // Provide non-ambiguous conversion to Kobject
994  operator Kobject const & () const noexcept
995  { return *static_cast<Base1 const *>(this); }
996 
997  // Provide non-ambiguous access of dec_refcnt()
998  l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
999  noexcept(noexcept(((Base1*)0)->dec_refcnt(diff, utcb)))
1000  { return Base1::dec_refcnt(diff, utcb); }
1001 };
1002 
1003 
1004 template< typename Derived, typename Base1, typename Base2, typename Base3,
1005  long PROTO, typename S_DEMAND >
1006 Type_info const *const
1007 Kobject_3t<Derived, Base1, Base2, Base3, PROTO, S_DEMAND>::__Kobject_typeid::_b[] =
1008 {
1009  &Base1::__Kobject_typeid::_m,
1010  &Base2::__Kobject_typeid::_m,
1011  &Base3::__Kobject_typeid::_m
1012 };
1013 
1018 template< typename Derived, typename Base1, typename Base2, typename Base3,
1019  long PROTO, typename S_DEMAND >
1020 L4____GEN_TI(Kobject_3t<Derived, Base1, Base2, Base3, PROTO, S_DEMAND>);
1021 
1022 }
1023 
1024 #if __cplusplus >= 201103L
1025 
1026 namespace L4 {
1027 
1034 template< typename ...T >
1036 
1037 template<>
1038 struct Kobject_demand<> : Type_info::Demand_t<> {};
1039 
1040 template<typename T>
1041 struct Kobject_demand<T> : Kobject_typeid<T>::Demand {};
1042 
1043 template<typename T1, typename ...T2>
1044 struct Kobject_demand<T1, T2...> :
1045  Type_info::Demand_union_t<typename Kobject_typeid<T1>::Demand,
1046  Kobject_demand<T2...> >
1047 {};
1048 
1049 namespace Typeid_xx {
1050 
1051  template<typename ...LISTS>
1052  struct Merge_list;
1053 
1054  template<typename L>
1055  struct Merge_list<L> : L {};
1056 
1057  template<typename L1, typename L2>
1058  struct Merge_list<L1, L2> : Typeid::Merge_list<L1, L2> {};
1059 
1060  template<typename L1, typename L2, typename ...LISTS>
1061  struct Merge_list<L1, L2, LISTS...> :
1062  Merge_list<typename Typeid::Merge_list<L1, L2>::type, LISTS...> {};
1063 
1064  template< typename I, typename ...LIST >
1065  struct Iface_conflict;
1066 
1067  template< typename I >
1068  struct Iface_conflict<I> : Typeid::False {};
1069 
1070  template< typename I, typename L, typename ...LIST >
1071  struct Iface_conflict<I, L, LIST...> :
1072  Typeid::Bool<Typeid::Iface_conflict<typename I::type, typename L::type>::value
1073  || Iface_conflict<I, LIST...>::value>
1074  {};
1075 
1076  template< typename ...LIST >
1077  struct Conflict;
1078 
1079  template< typename L >
1080  struct Conflict<L> : Typeid::False {};
1081 
1082  template< typename L1, typename L2, typename ...LIST >
1083  struct Conflict<L1, L2, LIST...> :
1084  Typeid::Bool<Typeid::Conflict<typename L1::type, typename L2::type>::value
1085  || Conflict<L1, LIST...>::value
1086  || Conflict<L2, LIST...>::value>
1087  {};
1088 
1089  template< typename T >
1090  struct Is_demand
1091  {
1092  static long test(Type_info::Demand const *);
1093  static char test(...);
1094  enum { value = sizeof(test((T*)0)) == sizeof(long) };
1095  };
1096 
1097  template< typename T, typename ... >
1098  struct First : T { typedef T type; };
1099 } // Typeid
1100 
1106 template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
1107 struct __Kobject_base : BASES...
1108 {
1109 protected:
1110  typedef Derived Class;
1111  typedef Typeid::Iface<PROTO, Derived> __Iface;
1112  typedef Typeid_xx::Merge_list<
1113  Typeid::Iface_list<__Iface>,
1114  typename BASES::__Iface_list...
1115  > __Iface_list;
1116 
1117  static void __check_protocols__() noexcept
1118  {
1119  typedef Typeid_xx::Iface_conflict<__Iface, typename BASES::__Iface_list...> Conflict;
1120  static_assert(!Conflict::value, "ambiguous protocol ID, protocol also used in base class");
1121 
1122  typedef Typeid_xx::Conflict<typename BASES::__Iface_list...> Base_conflict;
1123  static_assert(!Base_conflict::value, "ambiguous protocol IDs in base classes");
1124  }
1125 
1126  // disambiguate cap()
1127  l4_cap_idx_t cap() const noexcept
1128  { return Typeid_xx::First<BASES...>::type::cap(); }
1129 
1130  L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
1131 
1132  L4____GEN_TI_MEMBERS(Kobject_demand<BASES...>)
1133 
1134 private:
1135  // This function returns the first base class (used below)
1136  template<typename B1, typename ...> struct Base1 { typedef B1 type; };
1137 
1138 public:
1139  // Provide non-ambiguous conversion to Kobject
1140  operator Kobject const & () const noexcept
1141  { return *static_cast<typename Base1<BASES...>::type const *>(this); }
1142 
1143  // Provide non-ambiguous access of dec_refcnt()
1144  l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
1145  noexcept(noexcept(((typename Base1<BASES...>::type *)0)->dec_refcnt(diff, utcb)))
1146  { return Base1<BASES...>::type::dec_refcnt(diff, utcb); }
1147 };
1148 
1149 template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
1150 Type_info const *const
1151 __Kobject_base<Derived, PROTO, S_DEMAND, BASES...>::__Kobject_typeid::_b[] =
1152 {
1153  (&BASES::__Kobject_typeid::_m)...
1154 };
1155 
1156 template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
1157 L4____GEN_TI(__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>);
1158 
1159 
1160 // Test if the there is a Demand argument to Kobject_x
1161 template< typename Derived, long PROTO, bool HAS_DEMAND, typename DEMAND, typename ...ARGS >
1162 struct __Kobject_x_proto;
1163 
1164 // YES: pass it to __Kobject_base
1165 template< typename Derived, long PROTO, typename DEMAND, typename ...BASES>
1166 struct __Kobject_x_proto<Derived, PROTO, true, DEMAND, BASES...> :
1167  __Kobject_base<Derived, PROTO, DEMAND, BASES...> {};
1168 
1169 // NO: pass it empty Type_info::Demand_t
1170 template< typename Derived, long PROTO, typename B1, typename ...BASES>
1171 struct __Kobject_x_proto<Derived, PROTO, false, B1, BASES...> :
1172  __Kobject_base<Derived, PROTO, Type_info::Demand_t<>, B1, BASES...> {};
1173 
1181 template< long P = PROTO_EMPTY >
1182 struct Proto_t {};
1183 
1197 template< typename Derived, typename ...ARGS >
1198 struct Kobject_x;
1199 
1200 template< typename Derived, typename A, typename ...ARGS >
1201 struct Kobject_x<Derived, A, ARGS...> :
1202  __Kobject_x_proto<Derived, PROTO_ANY, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1203 {};
1204 
1205 template< typename Derived, long PROTO, typename A, typename ...ARGS >
1206 struct Kobject_x<Derived, Proto_t<PROTO>, A, ARGS...> :
1207  __Kobject_x_proto<Derived, PROTO, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1208 {};
1209 
1210 }
1211 #endif
1212 
1213 #undef L4____GEN_TI
1214 #undef L4____GEN_TI_MEMBERS
1215 
L4::Kobject_t::__check_protocols__
static void __check_protocols__() noexcept
Helper to check for protocol conflicts.
Definition: __typeinfo.h:772
L4::Kobject_2t::__check_protocols__
static void __check_protocols__() noexcept
Definition: __typeinfo.h:852
L4::Kobject_3t::__Iface_list
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:953
L4::Cap
C++ interface for capabilities.
Definition: capability.h:219
L4::Types::Bool< true >::type
Bool< V > type
The meta type itself.
Definition: types:302
L4::Type_info::Demand_t
Template type statically describing demand of receive buffers.
Definition: __typeinfo.h:564
L4::Kobject_t::__Iface_list
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
L4::Typeid::Rpcs
Standard list of RPCs of an interface.
Definition: __typeinfo.h:438
L4::Typeid::Detail::_Rpcs< OPCODE, O, R, X... >::type
_Rpcs type
The list element itself.
Definition: __typeinfo.h:382
l4_utcb
l4_utcb_t * l4_utcb(void) L4_NOTHROW L4_PURE
Get the UTCB address.
Definition: utcb.h:340
L4::Kobject_typeid::proto_dispatch
static int proto_dispatch(THIS *self, long proto, A1 a1, A2 &a2)
Protocol based server-side dispatch function.
Definition: __typeinfo.h:670
L4::Kobject_3t::c
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
Definition: __typeinfo.h:984
l4_cap_idx_t
unsigned long l4_cap_idx_t
L4 Capability selector Type.
Definition: types.h:342
L4::Kobject_t::c
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
Definition: __typeinfo.h:779
L4::Opcode
int Opcode
Data type for RPC opcodes.
Definition: __typeinfo.h:47
L4::Type_info::Demand::flags
unsigned char flags
flags, such as the need for timeouts (TBD).
Definition: __typeinfo.h:525
L4::Typeid::Rpcs_code::F
Definition: __typeinfo.h:455
L4::Kobject
Base class for all kinds of kernel objects and remote objects, referenced by capabilities.
Definition: kobject:47
L4::Typeid::Raw_ipc
RPCs list for passing raw incoming IPC to the server object.
Definition: __typeinfo.h:423
L4::Kobject_3t::__Iface
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition: __typeinfo.h:942
L4::Kobject_2t
Helper class to create an L4Re interface class that is derived from two base classes (see L4::Kobject...
Definition: __typeinfo.h:836
L4::Kobject_t::Class
Derived Class
The target interface type (inheriting from Kobject_t)
Definition: __typeinfo.h:763
L4_PROTO_META
@ L4_PROTO_META
Meta information protocol.
Definition: types.h:73
L4::Type_info::Demand::no_demand
bool no_demand() const noexcept
Definition: __typeinfo.h:542
L4::Type_info::Demand::ports
unsigned char ports
number of IO-port receive buffers.
Definition: __typeinfo.h:527
L4::Typeid::Detail::_Rpcs< OPCODE, O, R, X... >::opcode_type
OPCODE opcode_type
The data type for the opcode.
Definition: __typeinfo.h:384
L4::Kobject_typeid::Demand
T::__Kobject_typeid::Demand Demand
Data type expressing the static demand of receive buffers in a server.
Definition: __typeinfo.h:632
cxx::max
T1 max(T1 a, T1 b)
Get the maximum of a and b.
Definition: minmax:46
L4::Kobject_t::__Iface
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition: __typeinfo.h:765
L4::Kobject_2t::Class
Derived Class
The target interface type (inheriting from Kobject_t)
Definition: __typeinfo.h:839
L4::Kobject_t
Helper class to create an L4Re interface class that is derived from a single base class.
Definition: __typeinfo.h:760
L4::Kobject_3t
Helper class to create an L4Re interface class that is derived from three base classes (see L4::Kobje...
Definition: __typeinfo.h:937
L4::Proto_t
Data type for defining protocol numbers.
Definition: __typeinfo.h:1182
L4::Type_info::Demand::caps
unsigned char caps
number of capability receive buffers.
Definition: __typeinfo.h:524
L4::Kobject_3t::__check_protocols__
static void __check_protocols__() noexcept
Definition: __typeinfo.h:956
L4::Kobject_typeid::id
static Type_info const * id() noexcept
Get a pointer to teh Kobject type information of T.
Definition: __typeinfo.h:640
L4::Type_info::Demand
Data type for expressing the needed receive buffers at the server-side of an interface.
Definition: __typeinfo.h:517
L4::Type_info::Demand::Demand
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
L4::Type_info::Demand_union_t
Template type statically describing the combination of two Demand object.
Definition: __typeinfo.h:587
L4::Type_info
Dynamic Type Information for L4Re Interfaces.
Definition: __typeinfo.h:510
L4::PROTO_EMPTY
@ PROTO_EMPTY
Empty protocol for empty APIs.
Definition: __typeinfo.h:60
L4::Kobject_2t::__Iface
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition: __typeinfo.h:841
L4::Kobject_demand
Get the combined server-side resource requirements for all type T...
Definition: __typeinfo.h:1035
L4::Typeid::Detail::_Rpcs
Empty list of RPCs.
Definition: __typeinfo.h:375
L4::Kobject_2t::__Iface_list
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::Types::Bool
Boolean meta type.
Definition: types:301
L4
L4 low-level kernel interface.
Definition: l4sys-l4f-groups.dox:68
L4::Type_info::Demand::mem
unsigned char mem
number of memory receive buffers.
Definition: __typeinfo.h:526
L4::Types
L4 basic type helpers for C++.
Definition: types:31
L4::Kobject_2t::c
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
Definition: __typeinfo.h:871
L4::Kobject_x
Generic Kobject inheritance template.
Definition: __typeinfo.h:1198
L4::kobject_typeid
Type_info const * kobject_typeid() noexcept
Get the L4::Type_info for the L4Re interface given in T.
Definition: __typeinfo.h:692
L4::Typeid::Rpcs_code
List of RPCs of an interface using a special opcode type.
Definition: __typeinfo.h:450
L4::Kobject_3t::Class
Derived Class
The target interface type (inheriting from Kobject_t)
Definition: __typeinfo.h:940
L4::Typeid::P_dispatch
Use for protocol based dispatch stage.
Definition: __typeinfo.h:318
L4::Kobject_typeid
Meta object for handling access to type information of Kobjects.
Definition: __typeinfo.h:621
l4_utcb_t
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition: utcb.h:67
L4::Kobject_typeid::demand
static Type_info::Demand demand() noexcept
Get the receive-buffer demand for the server providing the interface T.
Definition: __typeinfo.h:649
l4_mword_t
signed long l4_mword_t
Signed machine word.
Definition: l4int.h:49
L4::Typeid::Detail::_Rpcs< OPCODE, O, R, X... >::next
_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
L4::Types::Flags
Template for defining typical Flags bitmaps.
Definition: types:64
L4::Typeid::Detail::_Rpcs< OPCODE, O, R, X... >::rpc
R rpc
The RPC type L4::Ipc::Msg::Rpc_call or L4::Ipc::Msg::Rpc_inline_call.
Definition: __typeinfo.h:386
L4::PROTO_ANY
@ PROTO_ANY
Default protocol used by Kobject_t and Kobject_x.
Definition: __typeinfo.h:58
L4::Types::False
False meta value.
Definition: types:308
L4::Typeid::Rpc_nocode
List of RPCs of an interface using a single operation without an opcode.
Definition: __typeinfo.h:464
l4_msgtag_t
Message tag data structure.
Definition: types.h:160
L4_EBADPROTO
@ L4_EBADPROTO
Unsupported protocol.
Definition: err.h:61
L4::Typeid::Detail::Rpcs_end
Internal end-of-list marker.
Definition: __typeinfo.h:328
L4::Types::True
True meta value.
Definition: types:312
L4::Typeid::Rpcs_sys
List of RPCs typically used for kernel interfaces.
Definition: __typeinfo.h:475
types