From 869fbc92b13d6a921cc220ef7e9d98d6bd8cb2dd Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Sun, 23 Mar 2014 23:46:37 +0100 Subject: [PATCH] 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 --- base/include/base/thread.h | 15 +++++++----- base/src/base/thread/context_allocator.cc | 30 ++++++++--------------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/base/include/base/thread.h b/base/include/base/thread.h index 61e357a912..3ac3afc33b 100644 --- a/base/include/base/thread.h +++ b/base/include/base/thread.h @@ -183,13 +183,16 @@ namespace Genode { Native_config::context_area_virtual_size() / Native_config::context_virtual_size(); - Bit_allocator _alloc; - Lock _threads_lock; + struct Context_bit_allocator : Bit_allocator + { + 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: diff --git a/base/src/base/thread/context_allocator.cc b/base/src/base/thread/context_allocator.cc index d83f455432..1d6a72d892 100644 --- a/base/src/base/thread/context_allocator.cc +++ b/base/src/base/thread/context_allocator.cc @@ -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::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)); }