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) noexcept
122  {
123  _items = (Counter*)m;
124  _capacity = capacity;
125  _bias = bias;
126  }
127 
128 public:
135  L4::Cap<void> alloc() noexcept
136  {
137  for (long i = _free_hint; i < _capacity; ++i)
138  {
139  if (_items[i].is_free())
140  {
141  _items[i].alloc();
142  _free_hint = i + 1;
143 
144  return L4::Cap<void>((i + _bias) << L4_CAP_SHIFT);
145  }
146  }
147 
148  return L4::Cap<void>::Invalid;
149  }
150 
152  template <typename T>
153  L4::Cap<T> alloc() noexcept
154  {
155  return L4::cap_cast<T>(alloc());
156  }
157 
158 
168  void take(L4::Cap<void> cap) noexcept
169  {
170  long c = cap.cap() >> L4_CAP_SHIFT;
171  if (c < _bias)
172  return;
173 
174  c -= _bias;
175  if (c >= _capacity)
176  return;
177 
178  _items[c].inc();
179  }
180 
181 
196  unsigned unmap_flags = L4_FP_ALL_SPACES) noexcept
197  {
198  long c = cap.cap() >> L4_CAP_SHIFT;
199  if (c < _bias)
200  return false;
201 
202  c -= _bias;
203 
204  if (c >= _capacity)
205  return false;
206 
207  l4_assert(!_items[c].is_free());
208 
209  if (l4_is_valid_cap(task))
210  l4_task_unmap(task, cap.fpage(), unmap_flags);
211 
212  if (c < _free_hint)
213  _free_hint = c;
214 
215  _items[c].free();
216 
217  return true;
218  }
219 
239  unsigned unmap_flags = L4_FP_ALL_SPACES) noexcept
240  {
241  long c = cap.cap() >> L4_CAP_SHIFT;
242  if (c < _bias)
243  return false;
244 
245  c -= _bias;
246 
247  if (c >= _capacity)
248  return false;
249 
250  l4_assert(!_items[c].is_free());
251 
252  if (_items[c].dec() == Counter::nil())
253  {
254  if (task != L4_INVALID_CAP)
255  l4_task_unmap(task, cap.fpage(), unmap_flags);
256 
257  if (c < _free_hint)
258  _free_hint = c;
259 
260  return true;
261  }
262  return false;
263  }
264 
265 
269  long last() noexcept
270  {
271  return _capacity + _bias - 1;
272  }
273 };
274 
275 }}
276 
Low-level assert implementation.
Constants.
Invalid capability selector.
Definition: consts.h:141
L4::Cap< T > alloc() noexcept
Allocate a new capability slot.
void setup(void *m, long capacity, long bias) noexcept
Set up the backing memory for the allocator and the area of managed capability slots.
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:346
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
bool release(L4::Cap< void > cap, l4_cap_idx_t task=L4_INVALID_CAP, unsigned unmap_flags=L4_FP_ALL_SPACES) noexcept
Decrease the reference counter for a capability.
Common task related definitions.
long last() noexcept
Return highest capability id managed by this allocator.
Flag to tell the unmap operation to unmap all child mappings including the mapping in the invoked tas...
Definition: consts.h:165
L4::Cap< void > alloc() noexcept
Allocate a new capability slot.
bool free(L4::Cap< void > cap, l4_cap_idx_t task=L4_INVALID_CAP, unsigned unmap_flags=L4_FP_ALL_SPACES) noexcept
Free the capability.
Capability index shift.
Definition: consts.h:131
#define l4_assert(expr)
Low-level assert.
Definition: assert.h:43
void take(L4::Cap< void > cap) noexcept
Increase the reference counter for the capability.
Internal reference-counting cap allocator.
Counter for Counting_cap_alloc with variable data width.
C++ interface for capabilities.
Definition: capability.h:13
Counting_cap_alloc() noexcept
Create a new, empty allocator.
Cap< T > cap_cast(Cap< F > const &c) noexcept
static_cast for capabilities.
Definition: capability.h:379