mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-06 01:11:46 +00:00
base: provide Thread_base::stack_size(size_t)
The new method enhances the stack of the targeted thread if it is smaller than a given size. ref #1075
This commit is contained in:
parent
c3b161e814
commit
3f9b098b70
@ -31,6 +31,40 @@ namespace Genode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Thread_base::Context::stack_size(size_t const size)
|
||||||
|
{
|
||||||
|
/* check if the stack needs to be enhanced */
|
||||||
|
size_t const stack_size = (addr_t)_stack - stack_base;
|
||||||
|
if (stack_size >= size) { return; }
|
||||||
|
|
||||||
|
/* check if the stack enhancement fits the context region */
|
||||||
|
enum {
|
||||||
|
CONTEXT_SIZE = Native_config::context_virtual_size(),
|
||||||
|
CONTEXT_AREA_BASE = Native_config::context_area_virtual_base(),
|
||||||
|
UTCB_SIZE = sizeof(Native_utcb),
|
||||||
|
PAGE_SIZE_LOG2 = 12,
|
||||||
|
PAGE_SIZE = (1UL << PAGE_SIZE_LOG2),
|
||||||
|
};
|
||||||
|
addr_t const context_base = Context_allocator::addr_to_base(this);
|
||||||
|
size_t const ds_size = align_addr(size - stack_size, PAGE_SIZE_LOG2);
|
||||||
|
if (stack_base - ds_size < context_base) { throw Stack_too_large(); }
|
||||||
|
|
||||||
|
/* allocate and attach backing store for the stack enhancement */
|
||||||
|
addr_t const ds_addr = stack_base - ds_size - CONTEXT_AREA_BASE;
|
||||||
|
try {
|
||||||
|
Ram_session * const ram = env_context_area_ram_session();
|
||||||
|
Ram_dataspace_capability const ds_cap = ram->alloc(ds_size);
|
||||||
|
Rm_session * const rm = env_context_area_rm_session();
|
||||||
|
void * const attach_addr = rm->attach_at(ds_cap, ds_addr, ds_size);
|
||||||
|
if (ds_addr != (addr_t)attach_addr) { throw Stack_alloc_failed(); }
|
||||||
|
}
|
||||||
|
catch (Ram_session::Alloc_failed) { throw Stack_alloc_failed(); }
|
||||||
|
|
||||||
|
/* update context information */
|
||||||
|
stack_base -= ds_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Thread_base::Context *
|
Thread_base::Context *
|
||||||
Thread_base::_alloc_context(size_t stack_size, bool main_thread)
|
Thread_base::_alloc_context(size_t stack_size, bool main_thread)
|
||||||
{
|
{
|
||||||
|
@ -112,6 +112,16 @@ namespace Genode {
|
|||||||
return ((addr_t)_stack & ~0xf) - Abi::stack_adjustment();
|
return ((addr_t)_stack & ~0xf) - Abi::stack_adjustment();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that the stack has a given size at the minimum
|
||||||
|
*
|
||||||
|
* \param size minimum stack size
|
||||||
|
*
|
||||||
|
* \throw Stack_too_large
|
||||||
|
* \throw Stack_alloc_failed
|
||||||
|
*/
|
||||||
|
void stack_size(size_t const size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Virtual address of the start of the stack
|
* Virtual address of the start of the stack
|
||||||
*
|
*
|
||||||
@ -421,6 +431,16 @@ namespace Genode {
|
|||||||
*/
|
*/
|
||||||
static Thread_base *myself();
|
static Thread_base *myself();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that the stack has a given size at the minimum
|
||||||
|
*
|
||||||
|
* \param size minimum stack size
|
||||||
|
*
|
||||||
|
* \throw Context::Stack_too_large
|
||||||
|
* \throw Context::Stack_alloc_failed
|
||||||
|
*/
|
||||||
|
void stack_size(size_t const size) { _context->stack_size(size); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return user-level thread control block
|
* Return user-level thread control block
|
||||||
*
|
*
|
||||||
|
@ -31,6 +31,40 @@ namespace Genode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Thread_base::Context::stack_size(size_t const size)
|
||||||
|
{
|
||||||
|
/* check if the stack needs to be enhanced */
|
||||||
|
size_t const stack_size = (addr_t)_stack - stack_base;
|
||||||
|
if (stack_size >= size) { return; }
|
||||||
|
|
||||||
|
/* check if the stack enhancement fits the context region */
|
||||||
|
enum {
|
||||||
|
CONTEXT_SIZE = Native_config::context_virtual_size(),
|
||||||
|
CONTEXT_AREA_BASE = Native_config::context_area_virtual_base(),
|
||||||
|
UTCB_SIZE = sizeof(Native_utcb),
|
||||||
|
PAGE_SIZE_LOG2 = 12,
|
||||||
|
PAGE_SIZE = (1UL << PAGE_SIZE_LOG2),
|
||||||
|
};
|
||||||
|
addr_t const context_base = Context_allocator::addr_to_base(this);
|
||||||
|
size_t const ds_size = align_addr(size - stack_size, PAGE_SIZE_LOG2);
|
||||||
|
if (stack_base - ds_size < context_base) { throw Stack_too_large(); }
|
||||||
|
|
||||||
|
/* allocate and attach backing store for the stack enhancement */
|
||||||
|
addr_t const ds_addr = stack_base - ds_size - CONTEXT_AREA_BASE;
|
||||||
|
try {
|
||||||
|
Ram_session * const ram = env_context_area_ram_session();
|
||||||
|
Ram_dataspace_capability const ds_cap = ram->alloc(ds_size);
|
||||||
|
Rm_session * const rm = env_context_area_rm_session();
|
||||||
|
void * const attach_addr = rm->attach_at(ds_cap, ds_addr, ds_size);
|
||||||
|
if (ds_addr != (addr_t)attach_addr) { throw Stack_alloc_failed(); }
|
||||||
|
}
|
||||||
|
catch (Ram_session::Alloc_failed) { throw Stack_alloc_failed(); }
|
||||||
|
|
||||||
|
/* update context information */
|
||||||
|
stack_base -= ds_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Thread_base::Context *
|
Thread_base::Context *
|
||||||
Thread_base::_alloc_context(size_t stack_size, bool main_thread)
|
Thread_base::_alloc_context(size_t stack_size, bool main_thread)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user