L4Re - L4 Runtime Environment
cap_alloc
Go to the documentation of this file.
1 // vi:set ft=cpp: -*- Mode: C++ -*-
2 /**
3  * \file
4  * \brief Abstract capability-allocator interface
5  */
6 /*
7  * (c) 2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
8  * Alexander Warg <warg@os.inf.tu-dresden.de>
9  * economic rights: Technische Universit├Ąt Dresden (Germany)
10  *
11  * This file is part of TUD:OS and distributed under the terms of the
12  * GNU General Public License 2.
13  * Please see the COPYING-GPL-2 file for details.
14  *
15  * As a special exception, you may use this file as part of a free software
16  * library without restriction. Specifically, if other files instantiate
17  * templates or use macros or inline functions from this file, or you compile
18  * this file and link it with other files to produce an executable, this
19  * file does not by itself cause the resulting executable to be covered by
20  * the GNU General Public License. This exception does not however
21  * invalidate any other reasons why the executable file might be covered by
22  * the GNU General Public License.
23  */
24 
25 #pragma once
26 
27 #include <l4/sys/task>
28 #include <l4/sys/smart_capability>
29 #include <l4/re/consts>
30 
31 namespace L4Re {
32 
33 /**
34  * \addtogroup l4re_cap_api
35  */
36 /*@{*/
37 /**
38  * \brief Capability allocator interface.
39  */
40 class Cap_alloc
41 {
42 private:
43  void operator = (Cap_alloc const &);
44 
45 protected:
46  Cap_alloc(Cap_alloc const &) {}
47  Cap_alloc() {}
48 
49 public:
50 
51  /**
52  * \brief Allocate a capability
53  * \return Capability of type void
54  */
55  virtual L4::Cap<void> alloc() throw() = 0;
56 
57  /**
58  * \brief Allocate a capability
59  * \return Capability of type T
60  */
61  template< typename T >
62  L4::Cap<T> alloc() throw()
63  { return L4::cap_cast<T>(alloc()); }
64 
65  /**
66  * \brief Free a capability
67  * \param cap Capability to free.
68  */
69  virtual void free(L4::Cap<void> cap) throw() = 0;
70 
71  //virtual L4::Cap<void> next_allocated(l4_umword_t *refs, L4::Cap<void> pivot = L4::Cap<void>::Invalid) throw() = 0;
72 
73  /**
74  * \brief Destructor.
75  */
76  virtual ~Cap_alloc() = 0;
77 
78  /**
79  * \brief Construct an instance of a capability allocator.
80  * \param ca Capability allocator
81  * \return Instance of a capability allocator.
82  */
83  template< typename CAP_ALLOC >
84  static inline L4Re::Cap_alloc *
85  get_cap_alloc(CAP_ALLOC &ca)
86  {
87  struct CA : public L4Re::Cap_alloc
88  {
89  CAP_ALLOC &_ca;
90  L4::Cap<void> alloc() throw() { return _ca.alloc(); }
91  void free(L4::Cap<void> cap) throw() { _ca.free(cap); }
92  CA(CAP_ALLOC &ca) : _ca(ca) {}
93  };
94 
95  static CA _ca(ca);
96  return &_ca;
97  }
98 };
99 
100 inline
101 Cap_alloc::~Cap_alloc()
102 {}
103 
104 
105 /**
106  * \brief Helper for Auto_cap and Auto_del_cap
107  * \ingroup api_l4re_util
108  */
109 template< unsigned long Unmap_flags = L4_FP_ALL_SPACES >
110 class Smart_cap_auto
111 {
112 private:
113  Cap_alloc *_ca;
114 
115 public:
116  Smart_cap_auto() : _ca(0) {}
117  Smart_cap_auto(Cap_alloc *ca) : _ca(ca) {}
118 
119  void free(L4::Cap_base &c)
120  {
121  if (c.is_valid() && _ca)
122  {
123  L4::Cap<L4::Task>(This_task)->unmap(c.fpage(), Unmap_flags);
124  _ca->free(L4::Cap<void>(c.cap()));
125  }
126  invalidate(c);
127  }
128 
129  static void invalidate(L4::Cap_base &c)
130  {
131  if (c.is_valid())
132  c.invalidate();
133  }
134 
135  static L4::Cap_base copy(L4::Cap_base const &src)
136  {
137  L4::Cap_base r = src;
138  invalidate(const_cast<L4::Cap_base &>(src));
139  return r;
140  }
141 };
142 
143 /**
144  * \internal the interface is not mature right now
145  * \brief Automatic capability that implements automatic free and
146  * unmap of the capability selector.
147  * \param T the type of the object that is referred by the capability.
148  *
149  * This kind of automatic capability is useful for capabilities
150  * that shall have a lifetime that is strictly coupled to one C++ scope.
151  *
152  * Usage:
153  * \code
154  * {
155  * L4Re::Auto_cap<L4Re::Dataspace>::Cap
156  * ds_cap(L4Re::cap_alloc.alloc<L4Re::Datasapce>));
157  *
158  * // use the dataspace cap
159  * L4Re::chksys(mem_alloc->alloc(4096, ds_cap.get()));
160  *
161  * ...
162  *
163  * // At the end of the scope ds_cap is unmapped and the capability selector
164  * // is freed.
165  * }
166  * \endcode
167  */
168 template< typename T >
169 struct Auto_cap
170 {
171  typedef L4::Smart_cap<T, Smart_cap_auto<> > Cap;
172 } L4_DEPRECATED("use L4::Re::Unique_cap");
173 
174 /**
175  * \internal the interface is not mature right now
176  * \brief Automatic capability that implements automatic free and
177  * unmap+delete of the capability selector.
178  * \param T the type of the object that is referred by the capability.
179  *
180  * This kind of automatic capability is useful for capabilities
181  * pointing to objects
182  * that shall have a lifetime that is strictly coupled to one C++ scope.
183  * The main difference to Auto_cap is that the unmap is done with the
184  * deletion flag enabled and this leads to the deletion of the object
185  * if the current task holds appropriate deletion rights.
186  *
187  * Usage:
188  * \code
189  * {
190  * L4Re::Auto_del_cap<L4Re::Dataspace>::Cap
191  * ds_cap(L4Re::cap_alloc.alloc<L4Re::Datasapce>));
192  *
193  * // use the dataspace cap
194  * L4Re::chksys(mem_alloc->alloc(4096, ds_cap.get()));
195  *
196  * ...
197  *
198  * // At the end of the scope ds_cap is unmapped and the capability selector
199  * // is freed. Because the deletion flag is set the data space shall be
200  * // also deleted (even if there are other references to this data space).
201  * }
202  * \endcode
203  */
204 template< typename T >
205 struct Auto_del_cap
206 {
207  typedef L4::Smart_cap<T, Smart_cap_auto<L4_FP_DELETE_OBJ> > Cap;
208 } L4_DEPRECATED("use L4::Re::Unique_del_cap");
209 /*@}*/
210 
211 }