base: generic implementation of Context_allocator

ref #989
This commit is contained in:
Martin Stein 2014-01-31 14:12:28 +01:00 committed by Norman Feske
parent 020edd3032
commit 523791b361
11 changed files with 96 additions and 160 deletions

View File

@ -21,7 +21,7 @@ SRC_CC += lock/lock.cc
SRC_CC += signal/signal.cc signal/common.cc
SRC_CC += server/server.cc server/common.cc
SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc
SRC_CC += env/utcb.cc
SRC_CC += thread/context_allocator.cc env/utcb.cc
SRC_CC += lock/cmpxchg.cc
INC_DIR += $(REP_DIR)/src/base/lock

View File

@ -21,6 +21,7 @@ SRC_CC += lock/lock.cc
SRC_CC += signal/signal.cc signal/common.cc
SRC_CC += server/server.cc server/common.cc
SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc
SRC_CC += thread/context_allocator.cc
INC_DIR += $(REP_DIR)/src/base/lock
INC_DIR += $(BASE_DIR)/src/base/thread

View File

@ -21,6 +21,7 @@ SRC_CC += env/spin_lock.cc env/cap_map.cc
SRC_CC += signal/signal.cc signal/common.cc
SRC_CC += server/server.cc server/common.cc
SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc
SRC_CC += thread/context_allocator.cc
INC_DIR += $(REP_DIR)/src/base/lock
INC_DIR += $(BASE_DIR)/src/base/lock

View File

@ -31,85 +31,6 @@ namespace Genode {
}
/******************************
** Thread-context allocator **
******************************/
Thread_base::Context *Thread_base::Context_allocator::base_to_context(addr_t base)
{
addr_t result = base + Native_config::context_virtual_size()
- sizeof(Context);
return reinterpret_cast<Context *>(result);
}
addr_t Thread_base::Context_allocator::addr_to_base(void *addr)
{
return ((addr_t)addr) & ~(Native_config::context_virtual_size() - 1);
}
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;
}
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() +
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);
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);
} catch(Bit_allocator<MAX_THREADS>::Out_of_indices) {
return 0;
}
}
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' */
_alloc.free(base_to_idx(base));
}
/*****************
** Thread base **
*****************/
Thread_base::Context_allocator *Thread_base::_context_allocator()
{
static Context_allocator context_allocator_inst;
return &context_allocator_inst;
}
Thread_base::Context *
Thread_base::_alloc_context(size_t stack_size, bool main_thread)
{

View File

@ -19,6 +19,7 @@ SRC_CC += lock/lock.cc
SRC_CC += signal/signal.cc signal/common.cc
SRC_CC += server/server.cc server/common.cc
SRC_CC += thread/thread_bootstrap.cc thread/trace.cc
SRC_CC += thread/context_allocator.cc
INC_DIR += $(REP_DIR)/src/base/lock
INC_DIR += $(BASE_DIR)/src/base/lock

View File

@ -19,7 +19,7 @@ SRC_CC += lock/lock.cc
SRC_CC += env/rm_session_mmap.cc env/debug.cc
SRC_CC += signal/signal.cc signal/common.cc
SRC_CC += server/server.cc server/common.cc
SRC_CC += thread/trace.cc thread/thread_env.cc
SRC_CC += thread/trace.cc thread/thread_env.cc thread/context_allocator.cc
INC_DIR += $(REP_DIR)/src/base/lock $(BASE_DIR)/src/base/lock
INC_DIR += $(REP_DIR)/src/base/ipc

View File

@ -19,7 +19,7 @@ SRC_CC += lock/lock.cc
SRC_CC += signal/signal.cc signal/common.cc
SRC_CC += server/server.cc
SRC_CC += thread/thread.cc thread/thread_context.cc thread/trace.cc
SRC_CC += env/cap_map.cc
SRC_CC += thread/context_allocator.cc env/cap_map.cc
INC_DIR += $(REP_DIR)/src/base/lock
INC_DIR += $(BASE_DIR)/src/base/lock

View File

@ -21,6 +21,7 @@ SRC_CC += lock/lock.cc
SRC_CC += signal/signal.cc signal/common.cc
SRC_CC += server/server.cc server/common.cc
SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc
SRC_CC += thread/context_allocator.cc
INC_DIR += $(REP_DIR)/src/base/lock
INC_DIR += $(BASE_DIR)/src/base/thread

View File

@ -21,6 +21,7 @@ SRC_CC += lock/lock.cc
SRC_CC += signal/signal.cc signal/common.cc
SRC_CC += server/server.cc server/common.cc
SRC_CC += thread/thread.cc thread/trace.cc thread/thread_bootstrap.cc
SRC_CC += thread/context_allocator.cc
INC_DIR += $(REP_DIR)/src/base/lock
INC_DIR += $(BASE_DIR)/src/base/thread

View File

@ -0,0 +1,88 @@
/*
* \brief Context-allocator implementation for the Genode Thread API
* \author Norman Feske
* \author Martin Stein
* \date 2014-01-26
*/
/*
* Copyright (C) 2010-2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/thread.h>
using namespace Genode;
Thread_base::Context *Thread_base::Context_allocator::base_to_context(addr_t base)
{
addr_t result = base + Native_config::context_virtual_size()
- sizeof(Context);
return reinterpret_cast<Context *>(result);
}
addr_t Thread_base::Context_allocator::addr_to_base(void *addr)
{
return ((addr_t)addr) & ~(Native_config::context_virtual_size() - 1);
}
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;
}
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();
}
Thread_base::Context *
Thread_base::Context_allocator::alloc(Thread_base *thread_base, bool main_thread)
{
Lock::Guard _lock_guard(_threads_lock);
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);
} catch(Bit_allocator<MAX_THREADS>::Out_of_indices) {
return 0;
}
}
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' */
_alloc.free(base_to_idx(base));
}
Thread_base::Context_allocator *Thread_base::_context_allocator()
{
static Context_allocator context_allocator_inst;
return &context_allocator_inst;
}

View File

@ -31,84 +31,6 @@ namespace Genode {
}
/******************************
** Thread-context allocator **
******************************/
Thread_base::Context *Thread_base::Context_allocator::base_to_context(addr_t base)
{
addr_t result = base + Native_config::context_virtual_size()
- sizeof(Context);
return reinterpret_cast<Context *>(result);
}
addr_t Thread_base::Context_allocator::addr_to_base(void *addr)
{
return ((addr_t)addr) & ~(Native_config::context_virtual_size() - 1);
}
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;
}
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();
}
Thread_base::Context *
Thread_base::Context_allocator::alloc(Thread_base *thread_base, bool main_thread)
{
Lock::Guard _lock_guard(_threads_lock);
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);
} catch(Bit_allocator<MAX_THREADS>::Out_of_indices) {
return 0;
}
}
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' */
_alloc.free(base_to_idx(base));
}
/*****************
** Thread base **
*****************/
Thread_base::Context_allocator *Thread_base::_context_allocator()
{
static Context_allocator context_allocator_inst;
return &context_allocator_inst;
}
Thread_base::Context *
Thread_base::_alloc_context(size_t stack_size, bool main_thread)
{