Loading...
Searching...
No Matches
__typeinfo.h
Go to the documentation of this file.
/*
* Copyright (C) 2014-2017, 2019, 2022-2024 Kernkonzept GmbH.
* Author(s): Alexander Warg <alexander.warg@kernkonzept.com>
*/
/*
* (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>
* economic rights: Technische Universität Dresden (Germany)
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#pragma GCC system_header
#include "cxx/types"
#include "cxx/ipc_basics"
#include "cxx/capability.h"
#if defined(__GXX_RTTI) && !defined(L4_NO_RTTI)
# include <typeinfo>
typedef std::type_info const *L4_std_type_info_ptr;
# define L4_KOBJECT_META_RTTI(type) (&typeid(type))
inline char const *L4_kobject_type_name(L4_std_type_info_ptr n) noexcept
{ return n ? n->name() : 0; }
#else
typedef void const *L4_std_type_info_ptr;
# define L4_KOBJECT_META_RTTI(type) (0)
inline char const *L4_kobject_type_name(L4_std_type_info_ptr) noexcept
{ return 0; }
#endif
namespace L4 {
typedef int Opcode;
// internal max helpers
namespace __I {
// internal max of A nd B helper
template< unsigned char A, unsigned char B>
struct Max { enum { Res = A > B ? A : B }; };
} // namespace __I
enum
{
PROTO_ANY = 0,
PROTO_EMPTY = -19,
};
namespace Typeid {
using namespace L4::Types;
/*********************/
template<long P, typename T>
struct Iface
{
typedef Iface type;
typedef T iface_type;
enum { Proto = P };
};
/*********************/
struct Iface_list_end
{
typedef Iface_list_end type;
static bool contains(long) noexcept { return false; }
};
template<typename I, typename N = Iface_list_end>
struct Iface_list
{
typedef Iface_list<I, N> type;
typedef typename I::iface_type iface_type;
typedef N Next;
enum { Proto = I::Proto };
static bool contains(long proto) noexcept
{ return (proto == Proto) || Next::contains(proto); }
};
// do not insert PROTO_EMPTY interfaces
template<typename I, typename N>
struct Iface_list<Iface<PROTO_EMPTY, I>, N> : N {};
// do not insert 'void' type interfaces
template<long P, typename N>
struct Iface_list<Iface<P, void>, N> : N {};
/*********************/
/*
* \internal
* Test if an interface I is in list L
* \tparam I Interface for lookup
* \tparam L Iface_list for search
*/
template< typename I, typename L >
struct _In_list;
template< typename I >
struct _In_list<I, Iface_list_end> : False {};
template< typename I, typename N >
struct _In_list<I, Iface_list<I, N> > : True {};
template< typename I, typename I2, typename N >
struct _In_list<I, Iface_list<I2, N> > : _In_list<I, typename N::type> {};
template<typename I, typename L>
struct In_list : _In_list<typename I::type, typename L::type> {};
/************/
/*
* \internal
* Add Helper: add I to interface list L if ADD is true
* \ingroup l4_cxx_ipc_internal
*/
template< bool ADD, typename I, typename L>
struct _Iface_list_add;
template< typename I, typename L>
struct _Iface_list_add<false, I, L> : L {};
template< typename I, typename L>
struct _Iface_list_add<true, I, L> : Iface_list<I, L> {};
/*
* \internal
* Add Helper: add I to interface list L if not already in L.
* \ingroup l4_cxx_ipc_internal
*/
template< typename I, typename L >
struct Iface_list_add :
_Iface_list_add<
!In_list<I, typename L::type>::value, I, typename L::type>
{};
/************/
/*
* \internal
* Helper: checking for a conflict between I2 and I2.
* A conflict means I1 and I2 have the same protocol ID but a different
* iface_type.
*/
template< typename I1, typename I2 >
struct __Iface_conflict : Bool<I1::Proto != PROTO_EMPTY && I1::Proto == I2::Proto> {};
template< typename I >
struct __Iface_conflict<I, I> : False {};
/*
* \internal
* Helper: checking for a conflict between I and any interface in LIST.
*/
template< typename I, typename LIST >
struct _Iface_conflict;
template< typename I >
struct _Iface_conflict<I, Iface_list_end> : False {};
template< typename I, typename I2, typename LIST >
struct _Iface_conflict<I, Iface_list<I2, LIST> > :
Bool<__Iface_conflict<I, I2>::value || _Iface_conflict<I, typename LIST::type>::value>
{};
template< typename I, typename LIST >
struct Iface_conflict : _Iface_conflict<typename I::type, typename LIST::type> {};
/**************/
/*
* \internal
* Helper: merge two interface lists
*/
template< typename L1, typename L2 >
struct _Merge_list;
template< typename L >
struct _Merge_list<Iface_list_end, L> : L {};
template< typename I, typename L1, typename L2 >
struct _Merge_list<Iface_list<I, L1>, L2> :
_Merge_list<typename L1::type, typename Iface_list_add<I, L2>::type> {};
template<typename L1, typename L2>
struct Merge_list : _Merge_list<typename L1::type, typename L2::type> {};
/**************/
/*
* \internal
* check for conflicts among all interfaces in L1 with any interfaces in L2.
*/
template< typename L1, typename L2 >
struct _Conflict;
template< typename L >
struct _Conflict<Iface_list_end, L> : False {};
template< typename I, typename L1, typename L2 >
struct _Conflict<Iface_list<I, L1>, L2> :
Bool<Iface_conflict<I, typename L2::type>::value
|| _Conflict<typename L1::type, typename L2::type>::value> {};
template< typename L1, typename L2 >
struct Conflict : _Conflict<typename L1::type, typename L2::type> {};
// to be removed ---------------------------------------
// p_dispatch code -- for legacy dispatch ------------------------------
/**********************/
/*
* \internal
* helper: Dispatch helper for calling server-side p_dispatch() functions.
*/
template<typename LIST>
struct _P_dispatch;
// No matching dispatcher found
template<>
struct _P_dispatch<Iface_list_end>
{
template< typename THIS, typename A1, typename A2 >
static int f(THIS *, long, A1, A2 &) noexcept
{ return -L4_EBADPROTO; }
};
// call matching p_dispatch() function
template< typename I, typename LIST >
struct _P_dispatch<Iface_list<I, LIST> >
{
// special handling for the meta protocol, to avoid 'using' murx
template< typename THIS, typename A1, typename A2 >
static int _f(THIS self, A1, A2 &a2, True::type)
{
return self->dispatch_meta_request(a2);
}
// normal p_dispatch() dispatching
template< typename THIS, typename A1, typename A2 >
static int _f(THIS self, A1 a1, A2 &a2, False::type)
{
return self->p_dispatch(reinterpret_cast<typename I::iface_type *>(0),
a1, a2);
}
// dispatch function with switch for meta protocol
template< typename THIS, typename A1, typename A2 >
static int f(THIS *self, long proto, A1 a1, A2 &a2)
{
if (I::Proto == proto)
return _f(self, a1, a2,
Bool<I::Proto == static_cast<long>(L4_PROTO_META)>());
return _P_dispatch<typename LIST::type>::f(self, proto, a1, a2);
}
};
template<typename LIST>
struct P_dispatch : _P_dispatch<typename LIST::type> {};
// end: p_dispatch -------------------------------------------------------
// end: to be removed ---------------------------------------
template<typename RPC> struct Default_op;
namespace Detail {
struct Rpcs_end
{
typedef void opcode_type;
typedef Rpcs_end rpc;
typedef Rpcs_end type;
};
template<typename O1, typename O2, typename RPCS>
struct _Rpc : _Rpc<typename RPCS::next::rpc, O2, typename RPCS::next>::type {};
template<typename O1, typename O2>
struct _Rpc<O1, O2, Rpcs_end> {};
template<typename OP, typename RPCS>
struct _Rpc<OP, OP, RPCS> : RPCS
{
typedef _Rpc type;
};
template<typename OP, typename RPCS>
struct Rpc : _Rpc<typename RPCS::rpc, OP, RPCS> {};
template<typename T, unsigned CODE>
struct _Get_opcode
{
template<bool, typename> struct Invalid_opcode {};
template<typename X> struct Invalid_opcode<true, X>;
private:
template<typename U, U> struct _chk;
template<typename U> static long _opc(_chk<int, U::Opcode> *);
template<typename U> static char _opc(...);
template<unsigned SZ, typename U>
struct _Opc { enum { value = CODE }; };
template<typename U>
struct _Opc<sizeof(long), U> { enum { value = U::Opcode }; };
public:
enum { value = _Opc<sizeof(_opc<T>(0)), T>::value };
Invalid_opcode<(value < CODE), T> invalid_opcode;
};
template<typename OPCODE, unsigned O, typename ...X>
struct _Rpcs : Rpcs_end {};
template<typename OPCODE, unsigned O, typename R, typename ...X>
struct _Rpcs<OPCODE, O, R, X...>
{
typedef _Rpcs type;
typedef OPCODE opcode_type;
typedef R rpc;
typedef typename _Rpcs<OPCODE, _Get_opcode<R, O>::value + 1, X...>::type next;
enum { Opcode = _Get_opcode<R, O>::value };
template<typename Y> struct Rpc : Typeid::Detail::Rpc<Y, _Rpcs> {};
};
template<typename OPCODE, unsigned O, typename R>
struct _Rpcs<OPCODE, O, Default_op<R> >
{
typedef _Rpcs type;
typedef void opcode_type;
typedef R rpc;
typedef Rpcs_end next;
enum { Opcode = -99 };
template<typename Y> struct Rpc : Typeid::Detail::Rpc<Y, _Rpcs> {};
};
} // namespace Detail
template<typename CLASS>
struct Raw_ipc
{
typedef Raw_ipc type;
typedef Detail::Rpcs_end next;
typedef void opcode_type;
};
template<typename ...RPCS>
struct Rpcs : Detail::_Rpcs<L4::Opcode, 0, RPCS...> {};
template<typename OPCODE_TYPE>
struct Rpcs_code
{
template<typename ...RPCS>
struct F : Detail::_Rpcs<OPCODE_TYPE, 0, RPCS...> {};
};
template<typename OPERATION>
struct Rpc_nocode : Detail::_Rpcs<void, 0, OPERATION> {};
template<typename ...ARG>
struct Rpcs_sys : Detail::_Rpcs<l4_umword_t, 0, ARG...> {};
template<typename CLASS>
struct Rights
{
unsigned rights;
Rights(unsigned rights) noexcept : rights(rights) {}
unsigned operator & (unsigned rhs) const noexcept { return rights & rhs; }
};
} // namespace Typeid
struct L4_EXPORT Type_info
{
class L4_EXPORT Demand
{
private:
static unsigned char max(unsigned char a, unsigned char b) noexcept
{ return a > b ? a : b; }
public:
unsigned char caps;
unsigned char flags;
unsigned char mem;
unsigned char ports;
explicit
Demand(unsigned char caps = 0, unsigned char flags = 0,
unsigned char mem = 0, unsigned char ports = 0) noexcept
: caps(caps), flags(flags), mem(mem), ports(ports) {}
bool no_demand() const noexcept
{ return caps == 0 && mem == 0 && ports == 0 && flags == 0; }
Demand operator | (Demand const &rhs) const noexcept
{
return Demand(max(caps, rhs.caps), flags | rhs.flags,
max(mem, rhs.mem), max(ports, rhs.ports));
}
};
template<unsigned char CAPS = 0, unsigned char FLAGS = 0,
unsigned char MEM = 0, unsigned char PORTS = 0>
struct Demand_t : Demand
{
enum
{
Caps = CAPS,
Flags = FLAGS,
Mem = MEM,
Ports = PORTS
};
Demand_t() noexcept : Demand(CAPS, FLAGS, MEM, PORTS) {}
};
template<typename D1, typename D2>
struct Demand_union_t : Demand_t<__I::Max<D1::Caps, D2::Caps>::Res,
D1::Flags | D2::Flags,
__I::Max<D1::Mem, D2::Mem>::Res,
__I::Max<D1::Ports, D2::Ports>::Res>
{};
L4_std_type_info_ptr _type;
Type_info const *const *_bases;
unsigned _num_bases;
long _proto;
L4_std_type_info_ptr type() const noexcept { return _type; }
Type_info const *base(unsigned idx) const noexcept { return _bases[idx]; }
unsigned num_bases() const noexcept { return _num_bases; }
long proto() const noexcept { return _proto; }
char const *name() const noexcept { return L4_kobject_type_name(type()); }
bool has_proto(long proto) const noexcept
{
if (_proto && _proto == proto)
return true;
if (!proto)
return false;
for (unsigned i = 0; i < _num_bases; ++i)
if (base(i)->has_proto(proto))
return true;
return false;
}
};
template<typename T> struct Kobject_typeid
{
typedef typename T::__Kobject_typeid::Demand Demand;
typedef typename T::__Iface::iface_type Iface;
typedef typename T::__Iface_list Iface_list;
static Type_info const *id() noexcept { return &T::__Kobject_typeid::_m; }
static Type_info::Demand demand() noexcept
{ return T::__Kobject_typeid::Demand(); }
// to be removed ---------------------------------------
// p_dispatch -----------------------------------------------------------
template<typename THIS, typename A1, typename A2>
static int proto_dispatch(THIS *self, long proto, A1 a1, A2 &a2)
{ return Typeid::P_dispatch<typename T::__Iface_list>::f(self, proto, a1, a2); }
// p_dispatch -----------------------------------------------------------
// end: to be removed ---------------------------------------
};
template<> struct Kobject_typeid<void>
{
typedef Type_info::Demand_t<> Demand;
};
template<typename T>
inline
Type_info const *kobject_typeid() noexcept
{ return Kobject_typeid<T>::id(); }
#define L4____GEN_TI(t...) \
Type_info const t::__Kobject_typeid::_m = \
{ \
L4_KOBJECT_META_RTTI(Derived), \
&t::__Kobject_typeid::_b[0], \
sizeof(t::__Kobject_typeid::_b) / sizeof(t::__Kobject_typeid::_b[0]), \
PROTO \
}
#define L4____GEN_TI_MEMBERS(BASE_DEMAND...) \
private: \
template< typename T > friend struct Kobject_typeid; \
protected: \
struct __Kobject_typeid { \
typedef Type_info::Demand_union_t<S_DEMAND, BASE_DEMAND> Demand; \
static Type_info const *const _b[]; \
static Type_info const _m; \
}; \
public: \
static long const Protocol = PROTO; \
typedef L4::Typeid::Rights<Class> Rights;
template<
typename Derived,
typename Base,
long PROTO = PROTO_ANY,
typename S_DEMAND = Type_info::Demand_t<>
>
class Kobject_t : public Base
{
protected:
typedef Derived Class;
typedef Typeid::Iface<PROTO, Derived> __Iface;
typedef Typeid::Merge_list<
Typeid::Iface_list<__Iface>, typename Base::__Iface_list
> __Iface_list;
static void __check_protocols__() noexcept
{
typedef Typeid::Iface_conflict<__Iface, typename Base::__Iface_list> Base_conflict;
static_assert(!Base_conflict::value, "ambiguous protocol ID: protocol also used by Base");
}
L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
// Generate the remaining type information
L4____GEN_TI_MEMBERS(typename Base::__Kobject_typeid::Demand)
};
template< typename Derived, typename Base, long PROTO, typename S_DEMAND>
Type_info const *const
Kobject_t<Derived, Base, PROTO, S_DEMAND>::
__Kobject_typeid::_b[] = { &Base::__Kobject_typeid::_m };
template< typename Derived, typename Base, long PROTO, typename S_DEMAND>
L4____GEN_TI(Kobject_t<Derived, Base, PROTO, S_DEMAND>);
template<
typename Derived,
typename Base1,
typename Base2,
long PROTO = PROTO_ANY,
typename S_DEMAND = Type_info::Demand_t<>
>
class Kobject_2t : public Base1, public Base2
{
protected:
typedef Derived Class;
typedef Typeid::Iface<PROTO, Derived> __Iface;
typedef Typeid::Merge_list<
Typeid::Iface_list<__Iface>,
Typeid::Merge_list<
typename Base1::__Iface_list,
typename Base2::__Iface_list
>
> __Iface_list;
static void __check_protocols__() noexcept
{
typedef typename Base1::__Iface_list Base1_proto_list;
typedef typename Base2::__Iface_list Base2_proto_list;
typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
static_assert(!Base1_conflict::value, "ambiguous protocol ID, also in Base1");
static_assert(!Base2_conflict::value, "ambiguous protocol ID, also in Base2");
typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Bases_conflict;
static_assert(!Bases_conflict::value, "ambiguous protocol IDs in base classes");
}
// disambiguate cap()
l4_cap_idx_t cap() const noexcept
{ return Base1::cap(); }
L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
L4____GEN_TI_MEMBERS(Type_info::Demand_union_t<
typename Base1::__Kobject_typeid::Demand,
typename Base2::__Kobject_typeid::Demand>
)
public:
// Provide non-ambiguous conversion to Kobject
operator Kobject const & () const noexcept
{ return *static_cast<Base1 const *>(this); }
// Provide non-ambiguous access of dec_refcnt()
l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
noexcept(noexcept(static_cast<Base1*>(nullptr)->dec_refcnt(diff, utcb)))
{ return Base1::dec_refcnt(diff, utcb); }
};
template< typename Derived, typename Base1, typename Base2,
long PROTO, typename S_DEMAND >
Type_info const *const
Kobject_2t<Derived, Base1, Base2, PROTO, S_DEMAND>::__Kobject_typeid::_b[] =
{
&Base1::__Kobject_typeid::_m,
&Base2::__Kobject_typeid::_m
};
template< typename Derived, typename Base1, typename Base2,
long PROTO, typename S_DEMAND >
L4____GEN_TI(Kobject_2t<Derived, Base1, Base2, PROTO, S_DEMAND>);
template<
typename Derived,
typename Base1,
typename Base2,
typename Base3,
long PROTO = PROTO_ANY,
typename S_DEMAND = Type_info::Demand_t<>
>
struct Kobject_3t : Base1, Base2, Base3
{
protected:
typedef Derived Class;
typedef Typeid::Iface<PROTO, Derived> __Iface;
typedef 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;
static void __check_protocols__() noexcept
{
typedef typename Base1::__Iface_list Base1_proto_list;
typedef typename Base2::__Iface_list Base2_proto_list;
typedef typename Base3::__Iface_list Base3_proto_list;
typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
typedef Typeid::Iface_conflict<__Iface, Base3_proto_list> Base3_conflict;
static_assert(!Base1_conflict::value, "ambiguous protocol ID, also in Base1");
static_assert(!Base2_conflict::value, "ambiguous protocol ID, also in Base2");
static_assert(!Base3_conflict::value, "ambiguous protocol ID, also in Base3");
typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Conflict_bases12;
typedef Typeid::Conflict<Base1_proto_list, Base3_proto_list> Conflict_bases13;
typedef Typeid::Conflict<Base2_proto_list, Base3_proto_list> Conflict_bases23;
static_assert(!Conflict_bases12::value, "ambiguous protocol IDs in base classes: Base1 and Base2");
static_assert(!Conflict_bases13::value, "ambiguous protocol IDs in base classes: Base1 and Base3");
static_assert(!Conflict_bases23::value, "ambiguous protocol IDs in base classes: Base2 and Base3");
}
// disambiguate cap()
l4_cap_idx_t cap() const noexcept
{ return Base1::cap(); }
L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
L4____GEN_TI_MEMBERS(Type_info::Demand_union_t<Type_info::Demand_union_t<
typename Base1::__Kobject_typeid::Demand,
typename Base2::__Kobject_typeid::Demand>,
typename Base3::__Kobject_typeid::Demand>
)
public:
// Provide non-ambiguous conversion to Kobject
operator Kobject const & () const noexcept
{ return *static_cast<Base1 const *>(this); }
// Provide non-ambiguous access of dec_refcnt()
l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
noexcept(noexcept(static_cast<Base1*>(nullptr)->dec_refcnt(diff, utcb)))
{ return Base1::dec_refcnt(diff, utcb); }
};
template< typename Derived, typename Base1, typename Base2, typename Base3,
long PROTO, typename S_DEMAND >
Type_info const *const
Kobject_3t<Derived, Base1, Base2, Base3, PROTO, S_DEMAND>::__Kobject_typeid::_b[] =
{
&Base1::__Kobject_typeid::_m,
&Base2::__Kobject_typeid::_m,
&Base3::__Kobject_typeid::_m
};
template< typename Derived, typename Base1, typename Base2, typename Base3,
long PROTO, typename S_DEMAND >
L4____GEN_TI(Kobject_3t<Derived, Base1, Base2, Base3, PROTO, S_DEMAND>);
}
#if __cplusplus >= 201103L
namespace L4 {
template< typename ...T >
struct Kobject_demand;
template<>
struct Kobject_demand<> : Type_info::Demand_t<> {};
template<typename T>
struct Kobject_demand<T> : Kobject_typeid<T>::Demand {};
template<typename T1, typename ...T2>
struct Kobject_demand<T1, T2...> :
Type_info::Demand_union_t<typename Kobject_typeid<T1>::Demand,
Kobject_demand<T2...> >
{};
namespace Typeid_xx {
template<typename ...LISTS>
struct Merge_list;
template<typename L>
struct Merge_list<L> : L {};
template<typename L1, typename L2>
struct Merge_list<L1, L2> : Typeid::Merge_list<L1, L2> {};
template<typename L1, typename L2, typename ...LISTS>
struct Merge_list<L1, L2, LISTS...> :
Merge_list<typename Typeid::Merge_list<L1, L2>::type, LISTS...> {};
template< typename I, typename ...LIST >
struct Iface_conflict;
template< typename I >
struct Iface_conflict<I> : Typeid::False {};
template< typename I, typename L, typename ...LIST >
struct Iface_conflict<I, L, LIST...> :
Typeid::Bool<Typeid::Iface_conflict<typename I::type, typename L::type>::value
|| Iface_conflict<I, LIST...>::value>
{};
template< typename ...LIST >
struct Conflict;
template< typename L >
struct Conflict<L> : Typeid::False {};
template< typename L1, typename L2, typename ...LIST >
struct Conflict<L1, L2, LIST...> :
Typeid::Bool<Typeid::Conflict<typename L1::type, typename L2::type>::value
|| Conflict<L1, LIST...>::value
|| Conflict<L2, LIST...>::value>
{};
template< typename T >
struct Is_demand
{
static long test(Type_info::Demand const *);
static char test(...);
enum { value = sizeof(test(static_cast<T*>(nullptr))) == sizeof(long) };
};
template< typename T, typename ... >
struct First : T { typedef T type; };
} // Typeid
template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
struct __Kobject_base : BASES...
{
protected:
typedef Derived Class;
typedef Typeid::Iface<PROTO, Derived> __Iface;
typedef Typeid_xx::Merge_list<
Typeid::Iface_list<__Iface>,
typename BASES::__Iface_list...
> __Iface_list;
static void __check_protocols__() noexcept
{
typedef Typeid_xx::Iface_conflict<__Iface, typename BASES::__Iface_list...> Conflict;
static_assert(!Conflict::value, "ambiguous protocol ID, protocol also used in base class");
typedef Typeid_xx::Conflict<typename BASES::__Iface_list...> Base_conflict;
static_assert(!Base_conflict::value, "ambiguous protocol IDs in base classes");
}
// disambiguate cap()
l4_cap_idx_t cap() const noexcept
{ return Typeid_xx::First<BASES...>::type::cap(); }
L4::Cap<Class> c() const noexcept { return L4::Cap<Class>(this->cap()); }
L4____GEN_TI_MEMBERS(Kobject_demand<BASES...>)
private:
// This function returns the first base class (used below)
template<typename B1, typename ...> struct Base1 { typedef B1 type; };
public:
// Provide non-ambiguous conversion to Kobject
operator Kobject const & () const noexcept
{ return *static_cast<typename Base1<BASES...>::type const *>(this); }
// Provide non-ambiguous access of dec_refcnt()
l4_msgtag_t dec_refcnt(l4_mword_t diff, l4_utcb_t *utcb = l4_utcb())
noexcept(noexcept(static_cast<typename Base1<BASES...>::type *>(nullptr)
->dec_refcnt(diff, utcb)))
{ return Base1<BASES...>::type::dec_refcnt(diff, utcb); }
};
template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
Type_info const *const
__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>::__Kobject_typeid::_b[] =
{
(&BASES::__Kobject_typeid::_m)...
};
template< typename Derived, long PROTO, typename S_DEMAND, typename ...BASES>
L4____GEN_TI(__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>);
// Test if the there is a Demand argument to Kobject_x
template< typename Derived, long PROTO, bool HAS_DEMAND, typename DEMAND, typename ...ARGS >
struct __Kobject_x_proto;
// YES: pass it to __Kobject_base
template< typename Derived, long PROTO, typename DEMAND, typename ...BASES>
struct __Kobject_x_proto<Derived, PROTO, true, DEMAND, BASES...> :
__Kobject_base<Derived, PROTO, DEMAND, BASES...> {};
// NO: pass it empty Type_info::Demand_t
template< typename Derived, long PROTO, typename B1, typename ...BASES>
struct __Kobject_x_proto<Derived, PROTO, false, B1, BASES...> :
__Kobject_base<Derived, PROTO, Type_info::Demand_t<>, B1, BASES...> {};
template< long P = PROTO_EMPTY >
struct Proto_t {};
template< typename Derived, typename ...ARGS >
struct Kobject_x;
template< typename Derived, typename A, typename ...ARGS >
struct Kobject_x<Derived, A, ARGS...> :
__Kobject_x_proto<Derived, PROTO_ANY, Typeid_xx::Is_demand<A>::value, A, ARGS...>
{};
template< typename Derived, long PROTO, typename A, typename ...ARGS >
struct Kobject_x<Derived, Proto_t<PROTO>, A, ARGS...> :
__Kobject_x_proto<Derived, PROTO, Typeid_xx::Is_demand<A>::value, A, ARGS...>
{};
}
#endif
#undef L4____GEN_TI
#undef L4____GEN_TI_MEMBERS
L4::Cap
C++ interface for capabilities.
Definition capability.h:224
L4::Kobject_2t
Helper class to create an L4Re interface class that is derived from two base classes (see L4::Kobject...
Definition __typeinfo.h:828
L4::Kobject_2t::Class
Derived Class
The target interface type (inheriting from Kobject_t).
Definition __typeinfo.h:831
L4::Kobject_2t::c
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
Definition __typeinfo.h:863
L4::Kobject_2t::__check_protocols__
static void __check_protocols__() noexcept
Helper to check for protocol conflicts.
Definition __typeinfo.h:844
L4::Kobject_2t::__Iface
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition __typeinfo.h:833
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:841
L4::Kobject_t
Helper class to create an L4Re interface class that is derived from a single base class.
Definition __typeinfo.h:750
L4::Kobject_t::__Iface
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition __typeinfo.h:755
L4::Kobject_t::c
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
Definition __typeinfo.h:769
L4::Kobject_t::__check_protocols__
static void __check_protocols__() noexcept
Helper to check for protocol conflicts.
Definition __typeinfo.h:762
L4::Kobject_t::Class
Derived Class
The target interface type (inheriting from Kobject_t).
Definition __typeinfo.h:753
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:759
L4::Kobject
Base class for all kinds of kernel objects and remote objects, referenced by capabilities.
Definition kobject:37
L4::Type_info::Demand
Data type for expressing the needed receive buffers at the server-side of an interface.
Definition __typeinfo.h:507
L4::Type_info::Demand::mem
unsigned char mem
number of memory receive buffers.
Definition __typeinfo.h:516
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:527
L4::Type_info::Demand::flags
unsigned char flags
flags, such as the need for timeouts (TBD).
Definition __typeinfo.h:515
L4::Type_info::Demand::no_demand
bool no_demand() const noexcept
Definition __typeinfo.h:532
L4::Type_info::Demand::caps
unsigned char caps
number of capability receive buffers.
Definition __typeinfo.h:514
L4::Type_info::Demand::ports
unsigned char ports
number of IO-port receive buffers.
Definition __typeinfo.h:517
l4_mword_t
signed long l4_mword_t
Signed machine word.
Definition l4int.h:37
l4_cap_idx_t
unsigned long l4_cap_idx_t
Capability selector type.
Definition types.h:336
L4_EBADPROTO
@ L4_EBADPROTO
Unsupported protocol.
Definition err.h:51
L4::kobject_typeid
Type_info const * kobject_typeid() noexcept
Get the L4::Type_info for the L4Re interface given in T.
Definition __typeinfo.h:682
l4_msgtag_t
struct l4_msgtag_t l4_msgtag_t
Message tag data structure.
L4_PROTO_META
@ L4_PROTO_META
Meta information protocol.
Definition types.h:63
l4_utcb_t
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition utcb.h:56
l4_utcb
l4_utcb_t * l4_utcb(void) L4_NOTHROW L4_PURE
Get the UTCB address.
Definition utcb.h:346
L4_EXPORT
#define L4_EXPORT
Attribute to mark functions, variables, and data types as being exported from a library.
Definition compiler.h:214
L4::Typeid
Definition of interface data-type helpers.
Definition __typeinfo.h:66
L4::Types
L4 basic type helpers for C++.
Definition types:20
L4
L4 low-level kernel interface.
Definition l4sys-l4f-groups.dox:50
L4::Opcode
int Opcode
Data type for RPC opcodes.
Definition __typeinfo.h:36
L4::PROTO_EMPTY
@ PROTO_EMPTY
Empty protocol for empty APIs.
Definition __typeinfo.h:49
L4::PROTO_ANY
@ PROTO_ANY
Default protocol used by Kobject_t and Kobject_x.
Definition __typeinfo.h:47
L4::Kobject_3t
Helper class to create an L4Re interface class that is derived from three base classes (see L4::Kobje...
Definition __typeinfo.h:931
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:947
L4::Kobject_3t::Class
Derived Class
The target interface type (inheriting from Kobject_t).
Definition __typeinfo.h:934
L4::Kobject_3t::__check_protocols__
static void __check_protocols__() noexcept
Helper to check for protocol conflicts.
Definition __typeinfo.h:950
L4::Kobject_3t::__Iface
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Definition __typeinfo.h:936
L4::Kobject_3t::c
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
Definition __typeinfo.h:978
L4::Kobject_demand
Get the combined server-side resource requirements for all type T...
Definition __typeinfo.h:1031
L4::Kobject_typeid
Meta object for handling access to type information of Kobjects.
Definition __typeinfo.h:611
L4::Kobject_typeid::id
static Type_info const * id() noexcept
Get a pointer to teh Kobject type information of T.
Definition __typeinfo.h:630
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:660
L4::Kobject_typeid::Demand
T::__Kobject_typeid::Demand Demand
Data type expressing the static demand of receive buffers in a server.
Definition __typeinfo.h:622
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:639
L4::Kobject_x
Generic Kobject inheritance template.
Definition __typeinfo.h:1197
L4::Proto_t
Data type for defining protocol numbers.
Definition __typeinfo.h:1181
L4::Type_info::Demand_t
Template type statically describing demand of receive buffers.
Definition __typeinfo.h:554
L4::Type_info::Demand_t::Caps
@ Caps
number of capability receive buffers.
Definition __typeinfo.h:557
L4::Type_info::Demand_t::Mem
@ Mem
number of memory receive windows.
Definition __typeinfo.h:559
L4::Type_info::Demand_t::Flags
@ Flags
flags, such as the need for timeouts.
Definition __typeinfo.h:558
L4::Type_info::Demand_t::Ports
@ Ports
number of IO-port receive windows.
Definition __typeinfo.h:560
L4::Type_info::Demand_union_t
Template type statically describing the combination of two Demand object.
Definition __typeinfo.h:577
L4::Type_info
Dynamic Type Information for L4Re Interfaces.
Definition __typeinfo.h:500
L4::Typeid::Detail::Rpcs_end
Internal end-of-list marker.
Definition __typeinfo.h:318
L4::Typeid::Detail::_Rpcs< OPCODE, O, Default_op< R > >::Rpc
Find the given RPC in the list.
Definition __typeinfo.h:399
L4::Typeid::Detail::_Rpcs< OPCODE, O, R, X... >::Rpc
Find the given RPC in the list.
Definition __typeinfo.h:382
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:376
L4::Typeid::Detail::_Rpcs< OPCODE, O, R, X... >::type
_Rpcs type
The list element itself.
Definition __typeinfo.h:372
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:378
L4::Typeid::Detail::_Rpcs< OPCODE, O, R, X... >::opcode_type
OPCODE opcode_type
The data type for the opcode.
Definition __typeinfo.h:374
L4::Typeid::Detail::type
L4::Typeid::P_dispatch
Use for protocol based dispatch stage.
Definition __typeinfo.h:308
L4::Typeid::Raw_ipc
RPCs list for passing raw incoming IPC to the server object.
Definition __typeinfo.h:413
L4::Typeid::Rpc_nocode
List of RPCs of an interface using a single operation without an opcode.
Definition __typeinfo.h:454
L4::Typeid::Rpcs_code::F
Definition __typeinfo.h:445
L4::Typeid::Rpcs_code
List of RPCs of an interface using a special opcode type.
Definition __typeinfo.h:440
L4::Typeid::Rpcs_sys
List of RPCs typically used for kernel interfaces.
Definition __typeinfo.h:465
L4::Typeid::Rpcs
Standard list of RPCs of an interface.
Definition __typeinfo.h:428
L4::Types::Bool
Boolean meta type.
Definition types:289
L4::Types::Bool< true >::type
Bool< V > type
Definition types:290
L4::Types::False
False meta value.
Definition types:296
L4::Types::True
True meta value.
Definition types:300
l4_msgtag_t
Message tag data structure.
Definition types.h:154
types