2016-01-23 14:42:55 +01:00
|
|
|
/*
|
|
|
|
* \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)
|
|
|
|
{
|
2016-03-03 17:57:29 +01:00
|
|
|
addr_t result = base + stack_virtual_size()
|
2016-01-23 14:42:55 +01:00
|
|
|
- sizeof(Stack);
|
|
|
|
return reinterpret_cast<Stack *>(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
addr_t Stack_allocator::addr_to_base(void *addr)
|
|
|
|
{
|
2016-03-03 17:57:29 +01:00
|
|
|
return ((addr_t)addr) & ~(stack_virtual_size() - 1);
|
2016-01-23 14:42:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t Stack_allocator::base_to_idx(addr_t base)
|
|
|
|
{
|
2016-03-03 17:57:29 +01:00
|
|
|
return (base - stack_area_virtual_base()) / stack_virtual_size();
|
2016-01-23 14:42:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
addr_t Stack_allocator::idx_to_base(size_t idx)
|
|
|
|
{
|
2016-03-03 17:57:29 +01:00
|
|
|
return stack_area_virtual_base() + idx * stack_virtual_size();
|
2016-01-23 14:42:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Stack *
|
|
|
|
Stack_allocator::alloc(Thread_base *thread_base, bool main_thread)
|
|
|
|
{
|
|
|
|
if (main_thread)
|
|
|
|
/* the main-thread stack is the first one */
|
2016-03-03 17:57:29 +01:00
|
|
|
return base_to_stack(stack_area_virtual_base());
|
2016-01-23 14:42:55 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|