mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-25 21:38:25 +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::_alloc_context(size_t stack_size, bool main_thread)
|
||||
{
|
||||
|
@ -112,6 +112,16 @@ namespace Genode {
|
||||
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
|
||||
*
|
||||
@ -421,6 +431,16 @@ namespace Genode {
|
||||
*/
|
||||
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
|
||||
*
|
||||
|
@ -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::_alloc_context(size_t stack_size, bool main_thread)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user