L4Re - L4 Runtime Environment
counting_cap_alloc
Go to the documentation of this file.
1 // vim:set ft=cpp: -*- Mode: C++ -*-
6 /*
7  * (c) 2008-2010 Alexander Warg <warg@os.inf.tu-dresden.de>
8  * economic rights: Technische Universität Dresden (Germany)
9  *
10  * This file is part of TUD:OS and distributed under the terms of the
11  * GNU General Public License 2.
12  * Please see the COPYING-GPL-2 file for details.
13  *
14  * As a special exception, you may use this file as part of a free software
15  * library without restriction. Specifically, if other files instantiate
16  * templates or use macros or inline functions from this file, or you compile
17  * this file and link it with other files to produce an executable, this
18  * file does not by itself cause the resulting executable to be covered by
19  * the GNU General Public License. This exception does not however
20  * invalidate any other reasons why the executable file might be covered by
21  * the GNU General Public License.
22  */
23 
24 #pragma once
25 
26 #include <l4/sys/task>
27 #include <l4/sys/assert.h>
28 #include <l4/re/consts>
29 
30 namespace L4Re { namespace Util {
31 
35 template< typename COUNTER = unsigned char >
36 struct Counter
37 {
38  typedef COUNTER Type;
39  Type _cnt;
40 
41  static Type nil() { return 0; }
42 
43  void free() { _cnt = 0; }
44  bool is_free() const { return _cnt == 0; }
45  void inc() { ++_cnt; }
46  Type dec() { return --_cnt; }
47  void alloc() { _cnt = 1; }
48 };
49 
74 template <typename COUNTERTYPE = L4Re::Util::Counter<unsigned char> >
76 {
77 private:
78  void operator = (Counting_cap_alloc const &) { }
79  typedef COUNTERTYPE Counter;
80 
81  COUNTERTYPE *_items;
82  long _free_hint;
83  long _bias;
84  long _capacity;
85 
86 
87 public:
88 
89  template <unsigned COUNT>
90  struct Counter_storage
91  {
92  COUNTERTYPE _buf[COUNT];
93  typedef COUNTERTYPE Buf_type[COUNT];
94  enum { Size = COUNT };
95  };
96 
97 protected:
98 
105  : _items(0), _free_hint(0), _bias(0), _capacity(0)
106  {}
107 
121  void setup(void *m, long capacity, long bias) throw()
122  {
123  _items = (Counter*)m;
124  _capacity = capacity;
125  _bias = bias;
126  }
127 
128 public:
136  {
137  if (_free_hint >= _capacity)
138  return L4::Cap_base::Invalid;
139 
140  for (long i = _free_hint; i < _capacity; ++i)
141  {
142  if (_items[i].is_free())
143  {
144  _items[i].alloc();
145  _free_hint = i + 1;
146 
147  return L4::Cap<void>((i + _bias) << L4_CAP_SHIFT);
148  }
149  }
150 
151  return L4::Cap<void>::Invalid;
152  }
153 
155  template <typename T>
156  L4::Cap<T> alloc() throw()
157  {
158  return L4::cap_cast<T>(alloc());
159  }
160 
161 
171  void take(L4::Cap<void> cap) throw()
172  {
173  long c = cap.cap() >> L4_CAP_SHIFT;
174  if (c < _bias)
175  return;
176 
177  c -= _bias;
178  if (c >= _capacity)
179  return;
180 
181  _items[c].inc();
182  }
183 
184 
199  unsigned unmap_flags = L4_FP_ALL_SPACES) throw()
200  {
201  long c = cap.cap() >> L4_CAP_SHIFT;
202  if (c < _bias)
203  return false;
204 
205  c -= _bias;
206 
207  if (c >= _capacity)
208  return false;
209 
210  l4_assert(!_items[c].is_free());
211 
212  if (l4_is_valid_cap(task))
213  l4_task_unmap(task, cap.fpage(), unmap_flags);
214 
215  if (c < _free_hint)
216  _free_hint = c;
217 
218  _items[c].free();
219 
220  return true;
221  }
222 
242  unsigned unmap_flags = L4_FP_ALL_SPACES) throw()
243  {
244  long c = cap.cap() >> L4_CAP_SHIFT;
245  if (c < _bias)
246  return false;
247 
248  c -= _bias;
249 
250  if (c >= _capacity)
251  return false;
252 
253  l4_assert(!_items[c].is_free());
254 
255  if (_items[c].dec() == Counter::nil())
256  {
257  if (task != L4_INVALID_CAP)
258  l4_task_unmap(task, cap.fpage(), unmap_flags);
259 
260  if (c < _free_hint)
261  _free_hint = c;
262 
263  return true;
264  }
265  return false;
266  }
267 
268 
272  long last() throw()
273  {
274  return _capacity + _bias - 1;
275  }
276 };
277 
278 }}
279 
long last()
Return highest capability id managed by this allocator.
Low-level assert implementation.
Invalid capability selector.
Definition: consts.h:141
Constants.
l4_msgtag_t l4_task_unmap(l4_cap_idx_t task, l4_fpage_t fpage, l4_umword_t map_mask) L4_NOTHROW
Revoke rights from the task.
Definition: task.h:376
unsigned l4_is_valid_cap(l4_cap_idx_t c) L4_NOTHROW
Test if a capability selector is a valid selector.
Definition: types.h:396
unsigned long l4_cap_idx_t
L4 Capability selector Type.
Definition: types.h:342
L4Re C++ Interfaces.
Definition: cmd_control:15
void take(L4::Cap< void > cap)
Increase the reference counter for the capability.
Common task related definitions.
L4::Cap< T > alloc()
Allocate a new capability slot.
void setup(void *m, long capacity, long bias)
Set up the backing memory for the allocator and the area of managed capability slots.
Flag to tell the unmap operation to unmap all child mappings including the mapping in the invoked tas...
Definition: consts.h:165
bool free(L4::Cap< void > cap, l4_cap_idx_t task=L4_INVALID_CAP, unsigned unmap_flags=L4_FP_ALL_SPACES)
Free the capability.
Capability index shift.
Definition: consts.h:131
bool release(L4::Cap< void > cap, l4_cap_idx_t task=L4_INVALID_CAP, unsigned unmap_flags=L4_FP_ALL_SPACES)
Decrease the reference counter for a capability.
#define l4_assert(expr)
Low-level assert.
Definition: assert.h:43
Counting_cap_alloc()
Create a new, empty allocator.
L4::Cap< void > alloc()
Allocate a new capability slot.
Internal reference-counting cap allocator.
Invalid capability selector.
Definition: capability.h:45
Cap< T > cap_cast(Cap< F > const &c)
static_cast for capabilities.
Definition: capability.h:379
Counter for Counting_cap_alloc with variable data width.
C++ interface for capabilities.
Definition: capability.h:13