base: allocate contexts solely inside context area

Reserve first bit in bit allocator for main thread of context allocator and
remove special cases in context allocator. Without the reservation there is
is one context outside the context area allocated.

Fixes #1100
This commit is contained in:
Alexander Boettcher 2014-03-23 23:46:37 +01:00 committed by Christian Helmuth
parent ced0f71f13
commit 869fbc92b1
2 changed files with 19 additions and 26 deletions

View File

@ -183,13 +183,16 @@ namespace Genode {
Native_config::context_area_virtual_size() /
Native_config::context_virtual_size();
Bit_allocator<MAX_THREADS> _alloc;
Lock _threads_lock;
struct Context_bit_allocator : Bit_allocator<MAX_THREADS>
{
Context_bit_allocator()
{
/* the first index is used by main thread */
_reserve(0, 1);
}
} _alloc;
/**
* Detect if a context already exists at the specified address
*/
bool _is_in_use(addr_t base);
Lock _threads_lock;
public:

View File

@ -34,34 +34,28 @@ addr_t Thread_base::Context_allocator::addr_to_base(void *addr)
size_t Thread_base::Context_allocator::base_to_idx(addr_t base)
{
/* the first context isn't managed through the indices */
return ((base - Native_config::context_area_virtual_base()) /
Native_config::context_virtual_size()) - 1;
return (base - Native_config::context_area_virtual_base()) /
Native_config::context_virtual_size();
}
addr_t Thread_base::Context_allocator::idx_to_base(size_t idx)
{
/* the first context isn't managed through the indices */
return Native_config::context_area_virtual_base() +
(idx + 1) * Native_config::context_virtual_size();
idx * Native_config::context_virtual_size();
}
Thread_base::Context *
Thread_base::Context_allocator::alloc(Thread_base *thread_base, bool main_thread)
{
Lock::Guard _lock_guard(_threads_lock);
if (main_thread)
/* the main-thread context is the first one */
return base_to_context(Native_config::context_area_virtual_base());
try {
addr_t base;
if (main_thread) {
/* the main-thread context isn't managed by '_alloc' */
base = Native_config::context_area_virtual_base();
} else {
/* contexts besides main-thread context are managed by '_alloc' */
base = idx_to_base(_alloc.alloc());
}
return base_to_context(base);
Lock::Guard _lock_guard(_threads_lock);
return base_to_context(idx_to_base(_alloc.alloc()));
} catch(Bit_allocator<MAX_THREADS>::Out_of_indices) {
return 0;
}
@ -70,13 +64,9 @@ Thread_base::Context_allocator::alloc(Thread_base *thread_base, bool main_thread
void Thread_base::Context_allocator::free(Context *context)
{
Lock::Guard _lock_guard(_threads_lock);
addr_t const base = addr_to_base(context);
/* the main-thread context isn't managed by '_alloc' */
if (base == Native_config::context_area_virtual_base()) { return; }
/* contexts besides main-thread context are managed by '_alloc' */
Lock::Guard _lock_guard(_threads_lock);
_alloc.free(base_to_idx(base));
}