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 bool is_saturated()
const {
return static_cast<Type
>(_cnt + 1) == 0; }
108template<
typename COUNTER =
unsigned char >
111 typedef COUNTER Type;
114 static Type nil() {
return 0; }
115 static Type unused() {
return 1; }
117 bool is_free()
const {
return __atomic_load_n(&_cnt, __ATOMIC_RELAXED) == 0; }
118 static bool is_saturated(Type cnt) {
return static_cast<Type
>(cnt + 1) == 0; }
122 Type expected = nil();
125 return __atomic_compare_exchange_n(&_cnt, &expected, 2,
false,
126 __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
134 Type old_cnt = __atomic_load_n(&_cnt, __ATOMIC_RELAXED);
138 if (is_saturated(old_cnt))
140 new_cnt = old_cnt + 1;
142 while (!__atomic_compare_exchange_n(&_cnt, &old_cnt, new_cnt,
false,
143 __ATOMIC_RELAXED, __ATOMIC_RELAXED));
144 if (is_saturated(new_cnt))
155 Type old_cnt = __atomic_load_n(&_cnt, __ATOMIC_RELAXED);
159 if (is_saturated(old_cnt))
161 new_cnt = old_cnt - 1;
163 while (!__atomic_compare_exchange_n(&_cnt, &old_cnt, new_cnt,
false,
164 __ATOMIC_RELAXED, __ATOMIC_RELAXED));
173 __atomic_store_n(&_cnt, 0, __ATOMIC_RELEASE);
201template <
typename COUNTERTYPE,
typename Dbg>
206 typedef COUNTERTYPE Counter;
216 template <
unsigned COUNT>
219 COUNTERTYPE _buf[COUNT];
220 typedef COUNTERTYPE Buf_type[COUNT];
221 enum { Size = COUNT };
232 : _items(0), _free_hint(0), _bias(0), _capacity(0)
236 : _items((
Counter*)m), _free_hint(0), _bias(bias), _capacity(capacity),
254 void setup(
void *m,
long capacity,
long bias, Dbg *dbg)
noexcept
256 _items =
static_cast<Counter*
>(m);
257 _capacity = capacity;
271 long free_hint = __atomic_load_n(&_free_hint, __ATOMIC_RELAXED);
273 for (
long i = free_hint; i < _capacity; ++i)
274 if (_items[i].try_alloc())
282 for (
long i = 0; i < free_hint && i < _capacity; ++i)
283 if (_items[i].try_alloc())
293 template <
typename T>
296 return L4::cap_cast<T>(
alloc());
311 if (!range_check_and_get_idx(cap, &c))
315 _dbg->printf(
"Warning: Reference counter of cap 0x%lx now saturated!\n",
337 if (!range_check_and_get_idx(cap, &c))
375 if (!range_check_and_get_idx(cap, &c))
380 if (_items[c].dec() == Counter::unused())
402 return _capacity + _bias - 1;
414 return *c < _capacity;
Internal reference-counting cap 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.
void setup(void *m, long capacity, long bias, Dbg *dbg) noexcept
Set up the backing memory for the allocator and the area of managed capability slots.
long last() noexcept
Return highest capability id managed by this allocator.
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 take(L4::Cap< void > cap) noexcept
Increase the reference counter for the capability.
L4::Cap< void > alloc() noexcept
Allocate a new capability slot.
L4::Cap< T > alloc() noexcept
Allocate a new capability slot.
Counting_cap_alloc() noexcept
Create a new, empty allocator.
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 ...
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
Thread safe version of counter for Counting_cap_alloc.
Type dec()
Decrement counter if not saturated.
bool inc()
Increment counter if not yet saturated.
Counter for Counting_cap_alloc with variable data width.
Type dec()
Decrement counter if not saturated.
bool inc()
Increment counter if not yet saturated.
Low-level assert implementation.
#define l4_assert(expr)
Low-level assert.
Common task related definitions.