19namespace L4Re {
namespace Util {
26template<
typename COUNTER =
unsigned char >
32 static Type nil() {
return 0; }
33 static Type unused() {
return 0; }
35 void free() { _cnt = 0; }
36 bool is_free()
const {
return _cnt == 0; }
37 bool is_saturated()
const {
return static_cast<Type
>(_cnt + 1) == 0; }
97template<
typename COUNTER =
unsigned char >
100 typedef COUNTER Type;
103 static Type nil() {
return 0; }
104 static Type unused() {
return 1; }
106 bool is_free()
const {
return __atomic_load_n(&_cnt, __ATOMIC_RELAXED) == 0; }
107 static bool is_saturated(Type cnt) {
return static_cast<Type
>(cnt + 1) == 0; }
111 Type expected = nil();
114 return __atomic_compare_exchange_n(&_cnt, &expected, 2,
false,
115 __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
123 Type old_cnt = __atomic_load_n(&_cnt, __ATOMIC_RELAXED);
127 if (is_saturated(old_cnt))
129 new_cnt = old_cnt + 1;
131 while (!__atomic_compare_exchange_n(&_cnt, &old_cnt, new_cnt,
false,
132 __ATOMIC_RELAXED, __ATOMIC_RELAXED));
133 if (is_saturated(new_cnt))
144 Type old_cnt = __atomic_load_n(&_cnt, __ATOMIC_RELAXED);
148 if (is_saturated(old_cnt))
150 new_cnt = old_cnt - 1;
152 while (!__atomic_compare_exchange_n(&_cnt, &old_cnt, new_cnt,
false,
153 __ATOMIC_RELAXED, __ATOMIC_RELAXED));
162 __atomic_store_n(&_cnt, 0, __ATOMIC_RELEASE);
190template <
typename COUNTERTYPE,
typename Dbg>
195 typedef COUNTERTYPE Counter;
205 template <
unsigned COUNT>
208 COUNTERTYPE _buf[COUNT];
209 typedef COUNTERTYPE Buf_type[COUNT];
210 enum { Size = COUNT };
214 : _items((Counter*)m), _free_hint(0), _bias(bias), _capacity(capacity),
225 : _items(0), _free_hint(0), _bias(0), _capacity(0)
242 void setup(
void *m,
long capacity,
long bias, Dbg *dbg)
noexcept
244 _items =
static_cast<Counter*
>(m);
245 _capacity = capacity;
259 long free_hint = __atomic_load_n(&_free_hint, __ATOMIC_RELAXED);
261 for (
long i = free_hint; i < _capacity; ++i)
262 if (_items[i].try_alloc())
270 for (
long i = 0; i < free_hint && i < _capacity; ++i)
271 if (_items[i].try_alloc())
281 template <
typename T>
284 return L4::cap_cast<T>(
alloc());
299 if (!range_check_and_get_idx(cap, &c))
303 _dbg->printf(
"Warning: Reference counter of cap 0x%lx now saturated!\n",
325 if (!range_check_and_get_idx(cap, &c))
363 if (!range_check_and_get_idx(cap, &c))
368 if (_items[c].dec() == Counter::unused())
390 return _capacity + _bias - 1;
402 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.