parent
6426d4098c
commit
ae12f04354
|
@ -61,7 +61,7 @@ namespace Genode {
|
||||||
Cap_range *find_by_id(addr_t);
|
Cap_range *find_by_id(addr_t);
|
||||||
|
|
||||||
void inc(unsigned id, bool inc_if_one = false);
|
void inc(unsigned id, bool inc_if_one = false);
|
||||||
void dec(unsigned id, bool revoke = true);
|
void dec(unsigned id, bool revoke = true, unsigned num_log2 = 0);
|
||||||
|
|
||||||
addr_t alloc(size_t const num_log2);
|
addr_t alloc(size_t const num_log2);
|
||||||
|
|
||||||
|
|
|
@ -63,15 +63,20 @@ void Cap_range::inc(unsigned id, bool inc_if_one)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Cap_range::dec(unsigned id, bool revoke)
|
void Cap_range::dec(unsigned const id_start, bool revoke, unsigned num_log_2)
|
||||||
{
|
{
|
||||||
bool failure = false;
|
bool failure = false;
|
||||||
{
|
{
|
||||||
|
unsigned const end = min(id_start + (1U << num_log_2), elements());
|
||||||
|
|
||||||
Lock::Guard guard(_lock);
|
Lock::Guard guard(_lock);
|
||||||
|
|
||||||
if (_cap_array[id] == 0)
|
for (unsigned id = id_start; id < end; id++) {
|
||||||
failure = true;
|
if (_cap_array[id] == 0) {
|
||||||
else {
|
failure = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (revoke && _cap_array[id] == 1)
|
if (revoke && _cap_array[id] == 1)
|
||||||
Nova::revoke(Nova::Obj_crd(_base + id, 0));
|
Nova::revoke(Nova::Obj_crd(_base + id, 0));
|
||||||
|
|
||||||
|
@ -80,8 +85,8 @@ void Cap_range::dec(unsigned id, bool revoke)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (failure)
|
if (failure)
|
||||||
PERR("cap reference counting error - count of cap=%lx is already zero",
|
PERR("cap reference counting error - one counter of cap range %lx+%x "
|
||||||
_base + id);
|
"has been already zero", _base + id_start, 1 << num_log_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -161,12 +166,23 @@ addr_t Capability_map::insert(size_t const num_log_2, addr_t const sel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Capability_map::remove(Genode::addr_t sel, uint8_t num_log_2, bool revoke)
|
void Capability_map::remove(Genode::addr_t const sel, uint8_t num_log_2,
|
||||||
|
bool revoke)
|
||||||
{
|
{
|
||||||
Cap_range * range = _tree.first() ? _tree.first()->find_by_id(sel) : 0;
|
Cap_range * range = _tree.first() ? _tree.first()->find_by_id(sel) : 0;
|
||||||
if (!range)
|
if (!range)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (unsigned i = 0; i < 1UL << num_log_2; i++)
|
range->dec(sel - range->base(), revoke, num_log_2);
|
||||||
range->dec(sel + i - range->base(), revoke);
|
|
||||||
|
Genode::addr_t last_sel = sel + (1UL << num_log_2);
|
||||||
|
Genode::addr_t last_range = range->base() + range->elements();
|
||||||
|
|
||||||
|
while (last_sel > last_range) {
|
||||||
|
uint8_t left_log2 = log2(last_sel - last_range);
|
||||||
|
|
||||||
|
remove(last_range, left_log2, revoke);
|
||||||
|
|
||||||
|
last_range += 1UL << left_log2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,13 +134,12 @@ void Thread_base::_deinit_platform_thread()
|
||||||
cap_map()->remove(_tid.ec_sel, 1, false);
|
cap_map()->remove(_tid.ec_sel, 1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
revoke(Obj_crd(_tid.exc_pt_sel, NUM_INITIAL_PT_LOG2));
|
|
||||||
cap_map()->remove(_tid.exc_pt_sel, NUM_INITIAL_PT_LOG2, false);
|
|
||||||
|
|
||||||
/* de-announce thread */
|
/* de-announce thread */
|
||||||
if (_thread_cap.valid())
|
if (_thread_cap.valid())
|
||||||
_cpu_session->kill_thread(_thread_cap);
|
_cpu_session->kill_thread(_thread_cap);
|
||||||
|
|
||||||
|
cap_map()->remove(_tid.exc_pt_sel, NUM_INITIAL_PT_LOG2);
|
||||||
|
|
||||||
if (_pager_cap.valid())
|
if (_pager_cap.valid())
|
||||||
env()->rm_session()->remove_client(_pager_cap);
|
env()->rm_session()->remove_client(_pager_cap);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue