|
|
@ -29,28 +29,35 @@ using namespace dev::eth; |
|
|
|
|
|
|
|
namespace |
|
|
|
{ |
|
|
|
|
|
|
|
static unsigned const c_depthLimit = 1024; |
|
|
|
|
|
|
|
/// Upper bound of stack space needed by single CALL/CREATE execution. Set experimentally.
|
|
|
|
static size_t const c_singleExecutionStackSize = 12 * 1024; |
|
|
|
|
|
|
|
/// Standard OSX thread stack limit. Should be reasonable for other platforms too.
|
|
|
|
static size_t const c_defaultStackSize = 512 * 1024; |
|
|
|
|
|
|
|
/// On what depth execution should be offloaded to additional separated stack space.
|
|
|
|
static unsigned const c_offloadPoint = c_defaultStackSize / c_singleExecutionStackSize; |
|
|
|
|
|
|
|
void goOnOffloadedStack(Executive& _e, OnOpFunc const& _onOp) |
|
|
|
{ |
|
|
|
cnote << "CALL OFFLOADING: offloading point " << c_offloadPoint; |
|
|
|
// Set new stack size enouth to handle the rest of the calls up to the limit.
|
|
|
|
boost::thread::attributes attrs; |
|
|
|
attrs.set_stack_size((c_depthLimit - c_offloadPoint) * c_singleExecutionStackSize); |
|
|
|
|
|
|
|
// Create new thread with big stack and join immediately.
|
|
|
|
// TODO: It is possible to switch the implementation to Boost.Context or similar when the API is stable.
|
|
|
|
std::exception_ptr exception; |
|
|
|
boost::thread{attrs, [&]{ |
|
|
|
cnote << "OFFLOADING thread"; |
|
|
|
try |
|
|
|
{ |
|
|
|
_e.go(_onOp); |
|
|
|
} |
|
|
|
catch (...) |
|
|
|
{ |
|
|
|
cnote << "!!!!!!!!!!! exception in offloading!!!!!!!!!!!!"; |
|
|
|
exception = std::current_exception(); |
|
|
|
exception = std::current_exception(); // Catch all exceptions to be rethrown in parent thread.
|
|
|
|
} |
|
|
|
}}.join(); |
|
|
|
if (exception) |
|
|
@ -59,6 +66,10 @@ void goOnOffloadedStack(Executive& _e, OnOpFunc const& _onOp) |
|
|
|
|
|
|
|
void go(unsigned _depth, Executive& _e, OnOpFunc const& _onOp) |
|
|
|
{ |
|
|
|
// If in the offloading point we need to switch to additional separated stack space.
|
|
|
|
// Current stack is too small to handle more CALL/CREATE executions.
|
|
|
|
// It needs to be done only once as newly allocated stack space it enough to handle
|
|
|
|
// the rest of the calls up to the depth limit (c_depthLimit).
|
|
|
|
if (_depth == c_offloadPoint) |
|
|
|
goOnOffloadedStack(_e, _onOp); |
|
|
|
else |
|
|
|