genode/repos/base/src/base/thread/stack_allocator.cc

79 lines
1.7 KiB
C++

/*
* \brief Stack-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.
*/
/* base-internal includes */
#include <base/internal/stack_allocator.h>
using namespace Genode;
Stack *Stack_allocator::base_to_stack(addr_t base)
{
addr_t result = base + Native_config::stack_virtual_size()
- sizeof(Stack);
return reinterpret_cast<Stack *>(result);
}
addr_t Stack_allocator::addr_to_base(void *addr)
{
return ((addr_t)addr) & ~(Native_config::stack_virtual_size() - 1);
}
size_t Stack_allocator::base_to_idx(addr_t base)
{
return (base - Native_config::stack_area_virtual_base()) /
Native_config::stack_virtual_size();
}
addr_t Stack_allocator::idx_to_base(size_t idx)
{
return Native_config::stack_area_virtual_base() +
idx * Native_config::stack_virtual_size();
}
Stack *
Stack_allocator::alloc(Thread_base *thread_base, bool main_thread)
{
if (main_thread)
/* the main-thread stack is the first one */
return base_to_stack(Native_config::stack_area_virtual_base());
try {
Lock::Guard _lock_guard(_threads_lock);
return base_to_stack(idx_to_base(_alloc.alloc()));
} catch(Bit_allocator<MAX_THREADS>::Out_of_indices) {
return 0;
}
}
void Stack_allocator::free(Stack *stack)
{
addr_t const base = addr_to_base(stack);
Lock::Guard _lock_guard(_threads_lock);
_alloc.free(base_to_idx(base));
}
Stack_allocator &Stack_allocator::stack_allocator()
{
static Stack_allocator inst;
return inst;
}