]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/types/types.h
8207e58ae4a9005706ceda65b8bd3161e8a4a166
[l4.git] / kernel / fiasco / src / types / types.h
1 #ifndef TYPES_H__
2 #define TYPES_H__
3
4 #include <stddef.h>
5 #include "types-arch.h"
6 #include "std_macros.h"
7
8 #ifdef __cplusplus
9
10 #include <type_traits>
11 #include <new>
12
13 template< typename a, typename b > inline
14 a nonull_static_cast( b p )
15 {
16   Address d = reinterpret_cast<Address>
17                  (static_cast<a>(reinterpret_cast<b>(10))) - 10;
18   return reinterpret_cast<a>( reinterpret_cast<Address>(p) + d);
19 }
20
21 template< typename T >
22 T access_once(T const *a)
23 {
24 #if 1
25   __asm__ __volatile__ ( "" : "=m"(*const_cast<T*>(a)));
26   T tmp = *a;
27   __asm__ __volatile__ ( "" : "=m"(*const_cast<T*>(a)));
28   return tmp;
29 #else
30   return *static_cast<T const volatile *>(a);
31 #endif
32 }
33
34 template< typename T >
35 void write_now(T *a, T const &val)
36 {
37   __asm__ __volatile__ ( "" : "=m"(*a));
38   *a = val;
39   __asm__ __volatile__ ( "" : : "m"(*a));
40 }
41
42 template< typename T >
43 class Static_object
44 {
45 private:
46   // prohibit copies
47   Static_object(Static_object const &) = delete;
48   Static_object &operator = (Static_object const &) = delete;
49
50 public:
51   Static_object() {}
52
53   T *get() const
54   {
55     return reinterpret_cast<T*>(&_i[0]);
56   }
57
58   operator T * () const { return get(); }
59   T *operator -> () const { return get(); }
60
61   T *construct()
62   { return new (_i) T; }
63
64   template< typename... A >
65   T *construct(A&&... args)
66   { return new (_i) T(cxx::forward<A>(args)...); }
67
68 private:
69   mutable char __attribute__((aligned(sizeof(Mword)*2))) _i[sizeof(T)];
70 };
71
72
73 template< typename VALUE, typename TARGET >
74 class Number
75 {
76 public:
77   typedef VALUE Value;
78   typedef TARGET Target;
79   struct Type_conversion_error;
80
81 protected:
82   Number() {}
83   explicit Number(Value v) : _v(v) {}
84
85 public:
86
87   static Target create(Value v)
88   { return Target(v); }
89
90   Target operator = (Target o)
91   { _v = o._v; return *static_cast<Target*>(this); }
92
93   Value value() const { return _v; }
94   Value value() const volatile { return _v; }
95   void set_value(Value v) { _v = v; }
96
97   bool operator < (Target const &o) const { return _v < o._v; }
98   bool operator > (Target const &o) const { return _v > o._v; }
99   bool operator <= (Target const &o) const { return _v <= o._v; }
100   bool operator >= (Target const &o) const { return _v >= o._v; }
101   bool operator == (Target const &o) const { return _v == o._v; }
102   bool operator != (Target const &o) const { return _v != o._v; }
103
104   operator Type_conversion_error const * () const
105   { return (Type_conversion_error const *)_v; }
106
107   Target operator | (Target const &o) const
108   { return Target(_v | o._v); }
109
110   Target operator & (Target const &o) const
111   { return Target(_v & o._v); }
112
113   Target operator + (Target const &o) const
114   { return Target(_v + o._v); }
115
116   Target operator - (Target const &o) const
117   { return Target(_v - o._v); }
118
119   Target operator << (unsigned long s) const
120   { return Target(_v << s); }
121
122   Target operator >> (unsigned long s) const
123   { return Target(_v >> s); }
124
125   void operator += (Target const &o) { _v += o._v; }
126   void operator -= (Target const &o) { _v -= o._v; }
127   void operator <<= (unsigned long s) { _v <<= s; }
128   void operator >>= (unsigned long s) { _v >>= s; }
129
130   Target operator ++ () { return Target(++_v); }
131   Target operator ++ (int) { return Target(_v++); }
132
133   Target operator -- () { return Target(--_v); }
134   Target operator -- (int) { return Target(_v--); }
135
136   Target trunc(Target const &size) const
137   { return Target(_v & ~(size._v - 1)); }
138
139   Target offset(Target const &size) const
140   { return Target(_v & (size._v - 1)); }
141
142   static Target from_shift(unsigned char shift)
143   {
144     if (shift >= (int)sizeof(Value) * 8)
145       return Target(Value(1) << Value((sizeof(Value) * 8 - 1)));
146     return Target(Value(1) << Value(shift));
147   }
148
149 protected:
150   Value _v;
151 };
152
153 template< int SHIFT >
154 class Page_addr : public Number<Address, Page_addr<SHIFT> >
155 {
156 private:
157   typedef Number<Address, Page_addr<SHIFT> > B;
158
159   template< int T >
160   class Itt
161   {};
162
163   template< int SH >
164   Address __shift(Address x, Itt<true>) { return x << SH; }
165
166   template< int SH >
167   Address __shift(Address x, Itt<false>) { return x >> (-SH); }
168
169 public:
170   enum { Shift = SHIFT };
171
172   template< int OSHIFT >
173   Page_addr(Page_addr<OSHIFT> o)
174   : B(__shift<Shift-OSHIFT>(o.value(), Itt<(OSHIFT < Shift)>()))
175   {}
176
177   explicit Page_addr(Address a) : B(a) {}
178
179   Page_addr(Page_addr const volatile &o) : B(o.value()) {}
180   Page_addr(Page_addr const &o) : B(o.value()) {}
181
182   Page_addr() {}
183 };
184
185 class Virt_addr : public Page_addr<ARCH_PAGE_SHIFT>
186 {
187 public:
188   template< int OSHIFT >
189   Virt_addr(Page_addr<OSHIFT> o) : Page_addr<ARCH_PAGE_SHIFT>(o) {}
190
191   explicit Virt_addr(unsigned int a) : Page_addr<ARCH_PAGE_SHIFT>(a) {}
192   explicit Virt_addr(int a) : Page_addr<ARCH_PAGE_SHIFT>(a) {}
193   explicit Virt_addr(long int a) : Page_addr<ARCH_PAGE_SHIFT>(a) {}
194   explicit Virt_addr(unsigned long a) : Page_addr<ARCH_PAGE_SHIFT>(a) {}
195   Virt_addr(void *a) : Page_addr<ARCH_PAGE_SHIFT>(Address(a)) {}
196
197   Virt_addr() {}
198 };
199
200 typedef Page_addr<ARCH_PAGE_SHIFT> Virt_size;
201
202 typedef Page_addr<0> Page_number;
203 typedef Page_number Page_count;
204
205 template<typename T>
206 struct Simple_ptr_policy
207 {
208   typedef T &Deref_type;
209   typedef T *Ptr_type;
210   typedef T *Member_type;
211   typedef T *Storage_type;
212
213   static void init(Storage_type const &) {}
214   static void init(Storage_type &d, Storage_type const &s) { d = s; }
215   static void copy(Storage_type &d, Storage_type const &s) { d = s; }
216   static void destroy(Storage_type const &) {}
217   static Deref_type deref(Storage_type p) { return *p; }
218   static Member_type member(Storage_type p) { return p; }
219   static Ptr_type ptr(Storage_type p) { return p; }
220 };
221
222 template<>
223 struct Simple_ptr_policy<void>
224 {
225   typedef void Deref_type;
226   typedef void *Ptr_type;
227   typedef void Member_type;
228   typedef void *Storage_type;
229
230   static void init(Storage_type const &) {}
231   static void init(Storage_type &d, Storage_type const &s) { d = s; }
232   static void copy(Storage_type &d, Storage_type const &s) { d = s; }
233   static void destroy(Storage_type const &) {}
234   static Deref_type deref(Storage_type p);
235   static Member_type member(Storage_type p);
236   static Ptr_type ptr(Storage_type p) { return p; }
237 };
238
239
240 template<typename T, template<typename P> class Policy = Simple_ptr_policy,
241          typename Discriminator = int>
242 class Smart_ptr
243 {
244 private:
245   struct Null_check_type;
246 public:
247   typedef typename Policy<T>::Deref_type Deref_type;
248   typedef typename Policy<T>::Ptr_type Ptr_type;
249   typedef typename Policy<T>::Member_type Member_type;
250   typedef typename Policy<T>::Storage_type Storage_type;
251
252   template<typename A, template<typename X> class B, typename C>
253   friend class Smart_ptr;
254
255 protected:
256   Storage_type _p;
257
258 public:
259   Smart_ptr()
260   { Policy<T>::init(_p); }
261
262   explicit Smart_ptr(T *p)
263   { Policy<T>::init(_p, p); }
264
265   Smart_ptr(Smart_ptr const &o)
266   { Policy<T>::copy(_p, o._p); }
267
268   template< typename RHT >
269   Smart_ptr(Smart_ptr<RHT, Policy, Discriminator> const &o)
270   { Policy<T>::copy(_p, o._p); }
271
272   ~Smart_ptr()
273   { Policy<T>::destroy(_p); }
274
275   Smart_ptr operator = (Smart_ptr const &o)
276   {
277     if (this == &o)
278       return *this;
279
280     Policy<T>::destroy(_p);
281     Policy<T>::copy(_p, o._p);
282     return *this;
283   }
284
285   Deref_type operator * () const
286   { return Policy<T>::deref(_p); }
287
288   Member_type operator -> () const
289   { return Policy<T>::member(_p); }
290
291   Ptr_type get() const
292   { return Policy<T>::ptr(_p); }
293
294   operator Null_check_type const * () const
295   { return reinterpret_cast<Null_check_type const *>(Policy<T>::ptr(_p)); }
296 };
297
298 enum User_ptr_discr {};
299
300 template<typename T>
301 struct User
302 {
303   typedef Smart_ptr<T, Simple_ptr_policy, User_ptr_discr> Ptr;
304 };
305 #endif
306
307 /// standard size type
308 ///typedef mword_t size_t;
309 ///typedef signed int ssize_t;
310
311 /// momentary only used in UX since there the kernel has a different
312 /// address space than user mode applications
313 enum Address_type { ADDR_KERNEL = 0, ADDR_USER = 1, ADDR_UNKNOWN = 2 };
314
315 #endif // TYPES_H__
316