]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re/util/include/cap_alloc
074813b0eb7a0dc8cdbaeda7480d3f42415ab4fe
[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  */
38 /*@{*/
39 /**
40  * \brief Capability allocator.
41  *
42  * This is the instance of the capability allocator that is used
43  * by usual applications.  The actual implementation of the allocator
44  * depends on the configuration of the system.
45  *
46  * Per default we use a reference count capability allocator, that
47  * keeps a reference counter for each managed capability selector.
48  *
49  * \note This capability allocator is not thread-safe.
50  */
51 extern _Cap_alloc &cap_alloc;
52
53 /**
54  * \brief Helper for Auto_cap and Auto_del_cap.
55  */
56 template< unsigned long Unmap_flags = L4_FP_ALL_SPACES >
57 class Smart_cap_auto
58 {
59 public:
60   /**
61    * \brief free operation for L4::Smart_cap.
62    */
63   static void free(L4::Cap_base &c)
64   {
65     if (c.is_valid())
66       {
67         cap_alloc.free(L4::Cap<void>(c.cap()), This_task, Unmap_flags);
68         c.invalidate();
69       }
70   }
71
72   /**
73    * \brief invalidate operation for L4::Smart_cap.
74    */
75   static void invalidate(L4::Cap_base &c)
76   {
77     if (c.is_valid())
78       c.invalidate();
79   }
80
81   /**
82    * \brief copy operation for L4::Smart_cap.
83    */
84   static L4::Cap_base copy(L4::Cap_base const &src)
85   {
86     L4::Cap_base r = src;
87     invalidate(const_cast<L4::Cap_base &>(src));
88     return r;
89   }
90 };
91
92
93 /**
94  * \brief Helper for Ref_cap and Ref_del_cap.
95  */
96 template< unsigned long Unmap_flags = L4_FP_ALL_SPACES >
97 class Smart_count_cap
98 {
99 public:
100   /**
101    * \brief free operation for L4::Smart_cap (decrement ref count and delete
102    *        if 0).
103    */
104   static void free(L4::Cap_base &c)
105   {
106     if (c.is_valid())
107       {
108         if (cap_alloc.release(L4::Cap<void>(c.cap()), This_task, Unmap_flags))
109           c.invalidate();
110       }
111   }
112
113   /**
114    * \brief invalidate operation for L4::Smart_cap.
115    */
116   static void invalidate(L4::Cap_base &c)
117   {
118     if (c.is_valid())
119       c.invalidate();
120   }
121
122   /**
123    * \brief copy operation for L4::Smart_cap (increment ref count).
124    */
125   static L4::Cap_base copy(L4::Cap_base const &src)
126   {
127     cap_alloc.take(L4::Cap<void>(src.cap()));
128     return src;
129   }
130 };
131
132
133 /**
134  * \brief Automatic capability that implements automatic free and
135  *        unmap of the capability selector.
136  * \param T the type of the object that is referred by the capability.
137  *
138  * This kind of automatic capability is useful for capabilities with
139  * that shall have a lifetime that is strictly coupled to one C++ scope.
140  *
141  * Usage:
142  * \code
143  * {
144  *   L4Re::Util::Auto_cap<L4Re::Dataspace>::Cap
145  *     ds_cap(L4Re::Util::cap_alloc.alloc<L4Re::Datasapce>));
146  *
147  *   // use the dataspace cap
148  *   L4Re::chksys(mem_alloc->alloc(4096, ds_cap.get()));
149  *
150  *   ...
151  *
152  *   // At the end of the scope ds_cap is unmapped and the capability selector
153  *   // is freed.
154  * }
155  * \endcode
156  */
157 template< typename T >
158 struct Auto_cap
159 {
160   typedef L4::Smart_cap<T, Smart_cap_auto< L4_FP_ALL_SPACES> > Cap;
161 };
162
163 /**
164  * \brief Automatic capability that implements automatic free and
165  *        unmap+delete of the capability selector.
166  * \param T the type of the object that is referred by the capability.
167  *
168  * This kind of automatic capability is useful for capabilities with
169  * that shall have a lifetime that is strictly coupled to one C++ scope.
170  * The main difference to Auto_cap is that the unmap is done with the
171  * deletion flag enabled and this leads to the deletion of the object
172  * if the current task holds appropriate deletion rights.
173  *
174  * Usage:
175  * \code
176  * {
177  *   L4Re::Util::Auto_del_cap<L4Re::Dataspace>::Cap
178  *     ds_cap(L4Re::Util::cap_alloc.alloc<L4Re::Datasapce>));
179  *
180  *   // use the dataspace cap
181  *   L4Re::chksys(mem_alloc->alloc(4096, ds_cap.get()));
182  *
183  *   ...
184  *
185  *   // At the end of the scope ds_cap is unmapped and the capability selector
186  *   // is freed. Because the deletion flag is set the data space shall be
187  *   // also deleted (even if there are other references to this data space).
188  * }
189  * \endcode
190  */
191 template< typename T >
192 struct Auto_del_cap
193 {
194   typedef L4::Smart_cap<T, Smart_cap_auto<L4_FP_DELETE_OBJ> > Cap;
195 };
196
197 /**
198  * \brief Automatic capability that implements automatic free and
199  *        unmap of the capability selector.
200  * \param T the type of the object that is referred by the capability.
201  *
202  * This kind of automatic capability implements a counted reference to a
203  * capability selector.  The capability shall be unmapped and freed
204  * when the reference count in the allocator goes to zero.
205  *
206  * Usage:
207  * \code
208  * L4Re::Util::Ref_cap<L4Re::Dataspace>::Ca global_ds_cap;
209  *
210  * {
211  *   L4Re::Util::Ref_cap<L4Re::Dataspace>::Cap
212  *     ds_cap(L4Re::Util::cap_alloc.alloc<L4Re::Datasapce>));
213  *   // reference count for the allocated cap selector is now 1
214  * *
215  *   // use the dataspace cap
216  *   L4Re::chksys(mem_alloc->alloc(4096, ds_cap.get()));
217  *
218  *   global_ds_cap = ds_cap;
219  *   // reference count is now 2
220  *   ...
221  * }
222  * // reference count dropped to 1 (ds_cap is no longer exiting).
223  * \endcode
224  */
225 template< typename T >
226 struct Ref_cap
227 {
228   typedef L4::Smart_cap<T, Smart_count_cap<L4_FP_ALL_SPACES> > Cap;
229 };
230
231 /**
232  * \brief Automatic capability that implements automatic free and
233  *        unmap+delete of the capability selector.
234  * \param T the type of the object that is referred by the capability.
235  *
236  * This kind of automatic capability implements a counted reference to a
237  * capability selector.  The capability shall be unmapped and freed
238  * when the reference count in the allocator goes to zero.
239  * The main difference to Ref_cap is that the unmap is done with the
240  * deletion flag enabled and this leads to the deletion of the object
241  * if the current task holds appropriate deletion rights.
242  *
243  * Usage:
244  * \code
245  * L4Re::Util::Ref_del_cap<L4Re::Dataspace>::Ca global_ds_cap;
246  *
247  * {
248  *   L4Re::Util::Ref_del_cap<L4Re::Dataspace>::Cap
249  *     ds_cap(L4Re::Util::cap_alloc.alloc<L4Re::Datasapce>));
250  *   // reference count for the allocated cap selector is now 1
251  *
252  *   // use the dataspace cap
253  *   L4Re::chksys(mem_alloc->alloc(4096, ds_cap.get()));
254  *
255  *   global_ds_cap = ds_cap;
256  *   // reference count is now 2
257  *   ...
258  * }
259  * // reference count dropped to 1 (ds_cap is no longer exiting).
260  * ...
261  * global_ds_cap = L4_INVALID_CAP;
262  * // reference count dropped to 0 (data space shall be deleted).
263  * \endcode
264  */
265 template< typename T >
266 struct Ref_del_cap
267 {
268   typedef L4::Smart_cap<T, Smart_count_cap<L4_FP_DELETE_OBJ> > Cap;
269 };
270
271 /*@}*/
272
273 }}
274