]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re/util/include/cap_alloc
update
[l4.git] / l4 / pkg / l4re / util / include / cap_alloc
1 // -*- Mode: C++ -*-
2 // vim:ft=cpp
3 /**
4  * \file
5  * \brief  Capability allocator
6  */
7 /*
8  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
9  *               Alexander Warg <warg@os.inf.tu-dresden.de>
10  *     economic rights: Technische Universität Dresden (Germany)
11  *
12  * This file is part of TUD:OS and distributed under the terms of the
13  * GNU General Public License 2.
14  * Please see the COPYING-GPL-2 file for details.
15  *
16  * As a special exception, you may use this file as part of a free software
17  * library without restriction.  Specifically, if other files instantiate
18  * templates or use macros or inline functions from this file, or you compile
19  * this file and link it with other files to produce an executable, this
20  * file does not by itself cause the resulting executable to be covered by
21  * the GNU General Public License.  This exception does not however
22  * invalidate any other reasons why the executable file might be covered by
23  * the GNU General Public License.
24  */
25
26 #pragma once
27
28 #include <l4/re/util/cap_alloc_impl.h>
29 #include <l4/sys/smart_capability>
30 #include <l4/sys/task>
31 #include <l4/re/consts>
32
33 namespace L4Re { namespace Util {
34
35 /**
36  * \defgroup l4re_cap_api L4Re Capability API
37  * \ingroup api_l4re_util
38  */
39 /*@{*/
40 /**
41  * \brief Capability allocator.
42  *
43  * This is the instance of the capability allocator that is used
44  * by usual applications.  The actual implementation of the allocator
45  * depends on the configuration of the system.
46  *
47  * Per default we use a reference count capability allocator, that
48  * keeps a reference counter for each managed capability selector.
49  *
50  * \note This capability allocator is not thread-safe.
51  */
52 extern _Cap_alloc &cap_alloc;
53
54 /**
55  * \brief Helper for Auto_cap and Auto_del_cap.
56  */
57 template< unsigned long Unmap_flags = L4_FP_ALL_SPACES >
58 class Smart_cap_auto
59 {
60 public:
61   /**
62    * \brief free operation for L4::Smart_cap.
63    */
64   static void free(L4::Cap_base &c)
65   {
66     if (c.is_valid())
67       {
68         cap_alloc.free(L4::Cap<void>(c.cap()), This_task, Unmap_flags);
69         c.invalidate();
70       }
71   }
72
73   /**
74    * \brief invalidate operation for L4::Smart_cap.
75    */
76   static void invalidate(L4::Cap_base &c)
77   {
78     if (c.is_valid())
79       c.invalidate();
80   }
81
82   /**
83    * \brief copy operation for L4::Smart_cap.
84    */
85   static L4::Cap_base copy(L4::Cap_base const &src)
86   {
87     L4::Cap_base r = src;
88     invalidate(const_cast<L4::Cap_base &>(src));
89     return r;
90   }
91 };
92
93
94 /**
95  * \brief Helper for Ref_cap and Ref_del_cap.
96  */
97 template< unsigned long Unmap_flags = L4_FP_ALL_SPACES >
98 class Smart_count_cap
99 {
100 public:
101   /**
102    * \brief free operation for L4::Smart_cap (decrement ref count and delete
103    *        if 0).
104    */
105   static void free(L4::Cap_base &c)
106   {
107     if (c.is_valid())
108       {
109         if (cap_alloc.release(L4::Cap<void>(c.cap()), This_task, Unmap_flags))
110           c.invalidate();
111       }
112   }
113
114   /**
115    * \brief invalidate operation for L4::Smart_cap.
116    */
117   static void invalidate(L4::Cap_base &c)
118   {
119     if (c.is_valid())
120       c.invalidate();
121   }
122
123   /**
124    * \brief copy operation for L4::Smart_cap (increment ref count).
125    */
126   static L4::Cap_base copy(L4::Cap_base const &src)
127   {
128     cap_alloc.take(L4::Cap<void>(src.cap()));
129     return src;
130   }
131 };
132
133
134 /**
135  * \brief Automatic capability that implements automatic free and
136  *        unmap of the capability selector.
137  * \param T the type of the object that is referred by the capability.
138  *
139  * This kind of automatic capability is useful for capabilities with
140  * that shall have a lifetime that is strictly coupled to one C++ scope.
141  *
142  * Usage:
143  * \code
144  * {
145  *   L4Re::Util::Auto_cap<L4Re::Dataspace>::Cap
146  *     ds_cap(L4Re::Util::cap_alloc.alloc<L4Re::Datasapce>));
147  *
148  *   // use the dataspace cap
149  *   L4Re::chksys(mem_alloc->alloc(4096, ds_cap.get()));
150  *
151  *   ...
152  *
153  *   // At the end of the scope ds_cap is unmapped and the capability selector
154  *   // is freed.
155  * }
156  * \endcode
157  */
158 template< typename T >
159 struct Auto_cap
160 {
161   typedef L4::Smart_cap<T, Smart_cap_auto< L4_FP_ALL_SPACES> > Cap;
162 };
163
164 /**
165  * \brief Automatic capability that implements automatic free and
166  *        unmap+delete of the capability selector.
167  * \param T the type of the object that is referred by the capability.
168  *
169  * This kind of automatic capability is useful for capabilities with
170  * that shall have a lifetime that is strictly coupled to one C++ scope.
171  * The main difference to Auto_cap is that the unmap is done with the
172  * deletion flag enabled and this leads to the deletion of the object
173  * if the current task holds appropriate deletion rights.
174  *
175  * Usage:
176  * \code
177  * {
178  *   L4Re::Util::Auto_del_cap<L4Re::Dataspace>::Cap
179  *     ds_cap(L4Re::Util::cap_alloc.alloc<L4Re::Datasapce>));
180  *
181  *   // use the dataspace cap
182  *   L4Re::chksys(mem_alloc->alloc(4096, ds_cap.get()));
183  *
184  *   ...
185  *
186  *   // At the end of the scope ds_cap is unmapped and the capability selector
187  *   // is freed. Because the deletion flag is set the data space shall be
188  *   // also deleted (even if there are other references to this data space).
189  * }
190  * \endcode
191  */
192 template< typename T >
193 struct Auto_del_cap
194 {
195   typedef L4::Smart_cap<T, Smart_cap_auto<L4_FP_DELETE_OBJ> > Cap;
196 };
197
198 /**
199  * \brief Automatic capability that implements automatic free and
200  *        unmap of the capability selector.
201  * \param T the type of the object that is referred by the capability.
202  *
203  * This kind of automatic capability implements a counted reference to a
204  * capability selector.  The capability shall be unmapped and freed
205  * when the reference count in the allocator goes to zero.
206  *
207  * Usage:
208  * \code
209  * L4Re::Util::Ref_cap<L4Re::Dataspace>::Ca global_ds_cap;
210  *
211  * {
212  *   L4Re::Util::Ref_cap<L4Re::Dataspace>::Cap
213  *     ds_cap(L4Re::Util::cap_alloc.alloc<L4Re::Datasapce>));
214  *   // reference count for the allocated cap selector is now 1
215  * *
216  *   // use the dataspace cap
217  *   L4Re::chksys(mem_alloc->alloc(4096, ds_cap.get()));
218  *
219  *   global_ds_cap = ds_cap;
220  *   // reference count is now 2
221  *   ...
222  * }
223  * // reference count dropped to 1 (ds_cap is no longer exiting).
224  * \endcode
225  */
226 template< typename T >
227 struct Ref_cap
228 {
229   typedef L4::Smart_cap<T, Smart_count_cap<L4_FP_ALL_SPACES> > Cap;
230 };
231
232 /**
233  * \brief Automatic capability that implements automatic free and
234  *        unmap+delete of the capability selector.
235  * \param T the type of the object that is referred by the capability.
236  *
237  * This kind of automatic capability implements a counted reference to a
238  * capability selector.  The capability shall be unmapped and freed
239  * when the reference count in the allocator goes to zero.
240  * The main difference to Ref_cap is that the unmap is done with the
241  * deletion flag enabled and this leads to the deletion of the object
242  * if the current task holds appropriate deletion rights.
243  *
244  * Usage:
245  * \code
246  * L4Re::Util::Ref_del_cap<L4Re::Dataspace>::Ca global_ds_cap;
247  *
248  * {
249  *   L4Re::Util::Ref_del_cap<L4Re::Dataspace>::Cap
250  *     ds_cap(L4Re::Util::cap_alloc.alloc<L4Re::Datasapce>));
251  *   // reference count for the allocated cap selector is now 1
252  *
253  *   // use the dataspace cap
254  *   L4Re::chksys(mem_alloc->alloc(4096, ds_cap.get()));
255  *
256  *   global_ds_cap = ds_cap;
257  *   // reference count is now 2
258  *   ...
259  * }
260  * // reference count dropped to 1 (ds_cap is no longer exiting).
261  * ...
262  * global_ds_cap = L4_INVALID_CAP;
263  * // reference count dropped to 0 (data space shall be deleted).
264  * \endcode
265  */
266 template< typename T >
267 struct Ref_del_cap
268 {
269   typedef L4::Smart_cap<T, Smart_count_cap<L4_FP_DELETE_OBJ> > Cap;
270 };
271
272 /*@}*/
273
274 }}
275