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_area_virtual_size() /
Native_config::context_virtual_size(); Native_config::context_virtual_size();
Bit_allocator<MAX_THREADS> _alloc; struct Context_bit_allocator : Bit_allocator<MAX_THREADS>
Lock _threads_lock; {
Context_bit_allocator()
{
/* the first index is used by main thread */
_reserve(0, 1);
}
} _alloc;
/** Lock _threads_lock;
* Detect if a context already exists at the specified address
*/
bool _is_in_use(addr_t base);
public: 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) 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()) /
return ((base - Native_config::context_area_virtual_base()) / Native_config::context_virtual_size();
Native_config::context_virtual_size()) - 1;
} }
addr_t Thread_base::Context_allocator::idx_to_base(size_t idx) 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() + 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 *
Thread_base::Context_allocator::alloc(Thread_base *thread_base, bool main_thread) 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 { try {
addr_t base; Lock::Guard _lock_guard(_threads_lock);
if (main_thread) { return base_to_context(idx_to_base(_alloc.alloc()));
/* 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);
} catch(Bit_allocator<MAX_THREADS>::Out_of_indices) { } catch(Bit_allocator<MAX_THREADS>::Out_of_indices) {
return 0; 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) void Thread_base::Context_allocator::free(Context *context)
{ {
Lock::Guard _lock_guard(_threads_lock);
addr_t const base = addr_to_base(context); addr_t const base = addr_to_base(context);
/* the main-thread context isn't managed by '_alloc' */ Lock::Guard _lock_guard(_threads_lock);
if (base == Native_config::context_area_virtual_base()) { return; }
/* contexts besides main-thread context are managed by '_alloc' */
_alloc.free(base_to_idx(base)); _alloc.free(base_to_idx(base));
} }