30namespace L4Re {
namespace Util {
37template<
typename COUNTER =
unsigned char >
43 static Type nil() {
return 0; }
44 static Type unused() {
return 0; }
46 void free() { _cnt = 0; }
47 bool is_free()
const {
return _cnt == 0; }
48 void inc() { ++_cnt; }
49 Type dec() {
return --_cnt; }
72template<
typename COUNTER =
unsigned char >
78 static Type nil() {
return 0; }
79 static Type unused() {
return 1; }
81 bool is_free()
const {
return __atomic_load_n(&_cnt, __ATOMIC_RELAXED) == 0; }
85 Type expected = nil();
88 return __atomic_compare_exchange_n(&_cnt, &expected, 2,
false,
89 __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
92 void inc() { __atomic_add_fetch(&_cnt, 1, __ATOMIC_RELAXED); }
93 Type dec() {
return __atomic_sub_fetch(&_cnt, 1, __ATOMIC_RELAXED); }
100 __atomic_store_n(&_cnt, 0, __ATOMIC_RELEASE);
128template <
typename COUNTERTYPE>
133 typedef COUNTERTYPE Counter;
143 template <
unsigned COUNT>
144 struct Counter_storage
146 COUNTERTYPE _buf[COUNT];
147 typedef COUNTERTYPE Buf_type[COUNT];
148 enum { Size = COUNT };
159 : _items(0), _free_hint(0), _bias(0), _capacity(0)
175 void setup(
void *m,
long capacity,
long bias)
noexcept
177 _items = (Counter*)m;
178 _capacity = capacity;
191 long free_hint = __atomic_load_n(&_free_hint, __ATOMIC_RELAXED);
193 for (
long i = free_hint; i < _capacity; ++i)
194 if (_items[i].try_alloc())
202 for (
long i = 0; i < free_hint && i < _capacity; ++i)
203 if (_items[i].try_alloc())
213 template <
typename T>
216 return L4::cap_cast<T>(
alloc());
232 if (!range_check_and_get_idx(cap, &c))
256 if (!range_check_and_get_idx(cap, &c))
294 if (!range_check_and_get_idx(cap, &c))
299 if (_items[c].dec() == Counter::unused())
321 return _capacity + _bias - 1;
333 return *c < _capacity;
Internal reference-counting cap allocator.
void take(L4::Cap< void > cap) noexcept
Increase the reference counter for the capability.
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.
void setup(void *m, long capacity, long bias) noexcept
Set up the backing memory for the allocator and the area of managed capability slots.
Counting_cap_alloc() noexcept
Create a new, empty allocator.
long last() noexcept
Return highest capability id managed by this allocator.
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.
L4::Cap< T > alloc() noexcept
Allocate a new capability slot.
l4_cap_idx_t cap() const noexcept
Return capability selector.
C++ interface for capabilities.
unsigned long l4_cap_idx_t
Capability selector type.
unsigned l4_is_valid_cap(l4_cap_idx_t c) L4_NOTHROW
Test if a capability selector is a valid selector.
@ L4_CAP_SHIFT
Capability index shift.
@ L4_INVALID_CAP
Invalid capability selector.
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.
@ L4_FP_ALL_SPACES
Flag to tell the unmap operation to revoke permissions from all child mappings including the mapping ...
Thread safe version of counter for Counting_cap_alloc.
Counter for Counting_cap_alloc with variable data width.
Low-level assert implementation.
#define l4_assert(expr)
Low-level assert.
Common task related definitions.