@@ -15,9 +15,6 @@ void resumable_main_benchmark_mem() | |||
{ | |||
using namespace std::chrono; | |||
resumef::state_t<void> st; | |||
std::cout << sizeof(st) << " " << sizeof(resumef::promise_t<>) << std::endl; | |||
for (size_t i = 0; i < N; ++i) | |||
{ | |||
go[=]()->resumef::future_t<size_t> |
@@ -180,6 +180,14 @@ namespace resumef | |||
_Alloc_char _Al; | |||
char* ptr = _Al.allocate(_Size + _State_size); | |||
//在初始地址上构造state | |||
{ | |||
state_type* st = new(ptr) state_type(coroutine_handle<promise_type>::from_promise(*(promise_type *)ptr)); | |||
st->lock(); | |||
*reinterpret_cast<uint32_t*>(ptr + _State_size) = static_cast<uint32_t>(_Size + _State_size); | |||
} | |||
return ptr + _State_size; | |||
} | |||
@@ -14,13 +14,7 @@ namespace resumef | |||
using promise_type = promise_t<value_type>; | |||
using future_type = future_t<value_type>; | |||
promise_impl_t() | |||
{ | |||
state_type* st = get_state(); | |||
new(st) state_type(); | |||
st->lock(); | |||
} | |||
promise_impl_t(){} | |||
promise_impl_t(promise_impl_t&& _Right) noexcept = default; | |||
promise_impl_t& operator = (promise_impl_t&& _Right) noexcept = default; | |||
promise_impl_t(const promise_impl_t&) = delete; | |||
@@ -47,23 +41,31 @@ namespace resumef | |||
{ | |||
size_t _State_size = _Align_size<state_type>(); | |||
assert(_Size >= sizeof(uint32_t) && _Size < (std::numeric_limits<uint32_t>::max)() - sizeof(_State_size)); | |||
#if RESUMEF_DEBUG_COUNTER | |||
std::cout << "future_promise::new, size=" << (_Size + _State_size) << std::endl; | |||
#endif | |||
_Alloc_char _Al; | |||
char* ptr = _Al.allocate(_Size + _State_size); | |||
#if RESUMEF_DEBUG_COUNTER | |||
std::cout << " future_promise::new, alloc size=" << (_Size + _State_size) << std::endl; | |||
std::cout << " future_promise::new, alloc ptr=" << (void*)ptr << std::endl; | |||
std::cout << " future_promise::new, return ptr=" << (void*)(ptr + _State_size) << std::endl; | |||
#endif | |||
//在初始地址上构造state | |||
{ | |||
state_type* st = new(ptr) state_type(_Size + _State_size); | |||
st->lock(); | |||
} | |||
return ptr + _State_size; | |||
} | |||
void operator delete(void* _Ptr, size_t _Size) | |||
void operator delete(void* _Ptr, size_t) | |||
{ | |||
size_t _State_size = _Align_size<state_type>(); | |||
assert(_Size >= sizeof(uint32_t) && _Size < (std::numeric_limits<uint32_t>::max)() - sizeof(_State_size)); | |||
_Alloc_char _Al; | |||
state_type* st = reinterpret_cast<state_type*>(static_cast<char*>(_Ptr) - _State_size); | |||
st->set_alloc_size(static_cast<uint32_t>(_Size + _State_size)); | |||
st->unlock(); | |||
} | |||
}; |
@@ -118,9 +118,9 @@ namespace resumef | |||
{ | |||
return _parent; | |||
} | |||
void set_alloc_size(uint32_t val) | |||
uint32_t get_alloc_size() const | |||
{ | |||
_alloc_size = val; | |||
return _alloc_size; | |||
} | |||
void set_exception(std::exception_ptr e); | |||
@@ -152,9 +152,9 @@ namespace resumef | |||
using state_future_t::lock_type; | |||
using value_type = _Ty; | |||
state_t() :state_future_t() | |||
explicit state_t(size_t alloc_size) :state_future_t() | |||
{ | |||
_alloc_size = sizeof(*this); | |||
_alloc_size = static_cast<uint32_t>(alloc_size); | |||
} | |||
explicit state_t(bool awaitor) :state_future_t(awaitor) | |||
{ | |||
@@ -189,9 +189,9 @@ namespace resumef | |||
{ | |||
using state_future_t::lock_type; | |||
state_t() :state_future_t() | |||
explicit state_t(size_t alloc_size) :state_future_t() | |||
{ | |||
_alloc_size = sizeof(*this); | |||
_alloc_size = static_cast<uint32_t>(alloc_size); | |||
} | |||
explicit state_t(bool awaitor) :state_future_t(awaitor) | |||
{ |
@@ -10,7 +10,7 @@ | |||
using namespace resumef; | |||
template<class _Ctype> | |||
void callback_get_long(int64_t val, _Ctype&& cb) | |||
static void callback_get_long(int64_t val, _Ctype&& cb) | |||
{ | |||
using namespace std::chrono; | |||
std::thread([val, cb = std::forward<_Ctype>(cb)] |
@@ -0,0 +1,139 @@ | |||
| |||
#include <chrono> | |||
#include <iostream> | |||
#include <string> | |||
#include <conio.h> | |||
#include <thread> | |||
#include "librf.h" | |||
using namespace resumef; | |||
template<class _Ctype> | |||
static void callback_get_long(int64_t a, int64_t b, _Ctype&& cb) | |||
{ | |||
std::cout << std::endl << __FUNCTION__ << " - begin" << std::endl; | |||
//编译失败。因为这个函数不是"可恢复函数(resumeable function)",甚至都不是"可等待函数(awaitable function)" | |||
//void* frame_ptr = _coro_frame_ptr(); | |||
using namespace std::chrono; | |||
std::thread([=, cb = std::forward<_Ctype>(cb)] | |||
{ | |||
std::this_thread::sleep_for(500ms); | |||
cb(a + b); | |||
}).detach(); | |||
std::cout << __FUNCTION__ << " - end" << std::endl; | |||
} | |||
//这种情况下,没有生成 frame-context,因此,并没有promise_type被内嵌在frame-context里 | |||
future_t<int64_t> awaitable_get_long(int64_t a, int64_t b) | |||
{ | |||
std::cout << std::endl << __FUNCTION__ << " - begin" << std::endl; | |||
//编译失败。因为这个函数不是"可恢复函数(resumeable function)",仅仅是"可等待函数(awaitable function)" | |||
//void* frame_ptr = _coro_frame_ptr(); | |||
resumef::awaitable_t<int64_t> awaitable; | |||
callback_get_long(a, b, [awaitable](int64_t val) | |||
{ | |||
awaitable.set_value(val); | |||
}); | |||
std::cout << __FUNCTION__ << " - end" << std::endl; | |||
return awaitable.get_future(); | |||
} | |||
future_t<int64_t> resumeable_get_long(int64_t x, int64_t y) | |||
{ | |||
std::cout << std::endl << __FUNCTION__ << " - begin" << std::endl; | |||
using future_type = future_t<int64_t>; | |||
using promise_type = typename future_type::promise_type; | |||
using state_type = typename future_type::state_type; | |||
void* frame_ptr = _coro_frame_ptr(); | |||
auto handler = coroutine_handle<promise_t<int64_t>>::from_address(frame_ptr); | |||
promise_type* promise = &handler.promise(); | |||
state_type* state = handler.promise().get_state(); | |||
std::cout << " future size=" << _Align_size<future_type>() << std::endl; | |||
std::cout << " promise size=" << _Align_size<promise_type>() << std::endl; | |||
std::cout << " state size=" << _Align_size<state_type>() << std::endl; | |||
std::cout << " frame size=" << _coro_frame_size() << ", alloc size=" << state->get_alloc_size() << std::endl; | |||
std::cout << " frame ptr=" << frame_ptr << "," << (void*)&frame_ptr << std::endl; | |||
std::cout << " frame end=" << (void*)((char*)(frame_ptr)+_coro_frame_size()) << std::endl; | |||
std::cout << " promise ptr=" << promise << "," << (void*)&promise << std::endl; | |||
std::cout << " handle ptr=" << handler.address() << "," << (void*)&handler << std::endl; | |||
std::cout << " state ptr=" << state << "," << (void*)&state << std::endl; | |||
std::cout << " parent ptr=" << state->get_parent() << std::endl; | |||
std::cout << " x=" << x << ", &x=" << std::addressof(x) << std::endl; | |||
std::cout << " y=" << y << ", &y=" << std::addressof(y) << std::endl; | |||
int64_t val = co_await awaitable_get_long(x, y); | |||
std::cout << " val=" << val << ", &val=" << std::addressof(val) << std::endl; | |||
std::cout << __FUNCTION__ << " - end" << std::endl; | |||
co_return val; | |||
} | |||
//这种情况下,会生成对应的 frame-context,一个promise_type被内嵌在frame-context里 | |||
future_t<> resumable_get_long_2(int64_t a, int64_t b, int64_t c) | |||
{ | |||
int64_t v1, v2, v3; | |||
std::cout << std::endl << __FUNCTION__ << " - begin" << std::endl; | |||
using future_type = future_t<int64_t>; | |||
using promise_type = typename future_type::promise_type; | |||
using state_type = typename future_type::state_type; | |||
void* frame_ptr = _coro_frame_ptr(); | |||
auto handler = coroutine_handle<promise_t<int64_t>>::from_address(frame_ptr); | |||
promise_type * promise = &handler.promise(); | |||
state_type * state = handler.promise().get_state(); | |||
std::cout << " future size=" << _Align_size<future_type>() << std::endl; | |||
std::cout << " promise size=" << _Align_size<promise_type>() << std::endl; | |||
std::cout << " state size=" << _Align_size<state_type>() << std::endl; | |||
std::cout << " frame size=" << _coro_frame_size() << ", alloc size=" << state->get_alloc_size() << std::endl; | |||
std::cout << " frame ptr=" << frame_ptr << ","<< (void*)&frame_ptr << std::endl; | |||
std::cout << " frame end=" << (void *)((char*)(frame_ptr) + _coro_frame_size()) << std::endl; | |||
std::cout << " promise ptr=" << promise << "," << (void *)&promise << std::endl; | |||
std::cout << " handle ptr=" << handler.address() << "," << (void*)&handler << std::endl; | |||
std::cout << " state ptr=" << state << "," << (void*)&state << std::endl; | |||
std::cout << " parent ptr=" << state->get_parent() << std::endl; | |||
std::cout << " a=" << a << ", &a=" << std::addressof(a) << std::endl; | |||
std::cout << " b=" << b << ", &b=" << std::addressof(b) << std::endl; | |||
std::cout << " c=" << c << ", &c=" << std::addressof(c) << std::endl; | |||
v1 = co_await resumeable_get_long(a, b); | |||
std::cout << " v1=" << v1 << ", &v1=" << std::addressof(v1) << std::endl; | |||
v2 = co_await resumeable_get_long(b, c); | |||
std::cout << " v2=" << v2 << ", &v2=" << std::addressof(v2) << std::endl; | |||
v3 = co_await resumeable_get_long(v1, v2); | |||
std::cout << " v3=" << v3 << ", &v3=" << std::addressof(v3) << std::endl; | |||
int64_t v4 = v1 * v2 * v3; | |||
std::cout << " v4=" << v4 << ", &v4=" << std::addressof(v4) << std::endl; | |||
std::cout << __FUNCTION__ << " - end" << std::endl; | |||
} | |||
void resumable_main_layout() | |||
{ | |||
std::cout << std::endl << __FUNCTION__ << " - begin" << std::endl; | |||
go resumable_get_long_2(1, 2, 5); | |||
resumef::this_scheduler()->run_until_notask(); | |||
std::cout << __FUNCTION__ << " - end" << std::endl; | |||
} |
@@ -13,17 +13,6 @@ future_t<> test_routine_use_timer() | |||
{ | |||
using namespace std::chrono; | |||
void* frame_ptr = _coro_frame_ptr(); | |||
size_t frame_size = _coro_frame_size(); | |||
std::cout << "test_routine_use_timer" << std::endl; | |||
std::cout << "frame point=" << frame_ptr << ", size=" << frame_size << ", promise_size=" << _Align_size<promise_t<>>() << std::endl; | |||
auto handler = coroutine_handle<promise_t<>>::from_address(frame_ptr); | |||
auto st = handler.promise().get_state(); | |||
scheduler_t* sch = st->get_scheduler(); | |||
auto parent = st->get_parent(); | |||
std::cout << "st=" << st << ", scheduler=" << sch << ", parent=" << parent << std::endl; | |||
for (size_t i = 0; i < 3; ++i) | |||
{ | |||
co_await resumef::sleep_for(100ms); |
@@ -21,6 +21,7 @@ extern void resumable_main_modern_cb(); | |||
extern void resumable_main_multi_thread(); | |||
extern void resumable_main_channel_mult_thread(); | |||
extern void resumable_main_when_all(); | |||
extern void resumable_main_layout(); | |||
extern void resumable_main_benchmark_mem(); | |||
extern void benchmark_main_channel_passing_next(); | |||
@@ -31,7 +32,7 @@ int main(int argc, const char* argv[]) | |||
{ | |||
(void)argc; | |||
(void)argv; | |||
resumable_main_yield_return(); | |||
resumable_main_layout(); | |||
//if (argc > 1) | |||
// resumable_main_benchmark_asio_client(atoi(argv[1])); | |||
@@ -39,6 +40,7 @@ int main(int argc, const char* argv[]) | |||
// resumable_main_benchmark_asio_server(); | |||
//resumable_main_cb(); | |||
//resumable_main_layout(); | |||
//resumable_main_modern_cb(); | |||
//resumable_main_suspend_always(); | |||
//resumable_main_yield_return(); |
@@ -42,13 +42,13 @@ | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | |||
<ConfigurationType>Application</ConfigurationType> | |||
<UseDebugLibraries>true</UseDebugLibraries> | |||
<PlatformToolset>v141</PlatformToolset> | |||
<PlatformToolset>v142</PlatformToolset> | |||
<CharacterSet>NotSet</CharacterSet> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> | |||
<ConfigurationType>Application</ConfigurationType> | |||
<UseDebugLibraries>false</UseDebugLibraries> | |||
<PlatformToolset>v141</PlatformToolset> | |||
<PlatformToolset>v142</PlatformToolset> | |||
<WholeProgramOptimization>true</WholeProgramOptimization> | |||
<CharacterSet>NotSet</CharacterSet> | |||
</PropertyGroup> | |||
@@ -104,16 +104,17 @@ | |||
<ClCompile> | |||
<WarningLevel>Level3</WarningLevel> | |||
<Optimization>Disabled</Optimization> | |||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;ASIO_STANDALONE;RESUMEF_DEBUG_COUNTER=1;RESUMEF_ENABLE_MULT_SCHEDULER=1;RESUMEF_USE_BOOST_ANY=0;_SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING=1;ASIO_DISABLE_CONCEPTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;ASIO_STANDALONE;RESUMEF_DEBUG_COUNTER=0;RESUMEF_ENABLE_MULT_SCHEDULER=1;RESUMEF_USE_BOOST_ANY=0;_SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING=1;ASIO_DISABLE_CONCEPTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||
<SDLCheck>true</SDLCheck> | |||
<AdditionalIncludeDirectories>..\librf;..\..\asio\asio\include;..\..\asio-1.10.6\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |||
<AdditionalOptions>/await</AdditionalOptions> | |||
<MultiProcessorCompilation>true</MultiProcessorCompilation> | |||
<LanguageStandard>stdcpp17</LanguageStandard> | |||
<LanguageStandard>stdcpplatest</LanguageStandard> | |||
<MinimalRebuild /> | |||
<CLanguageStandard>c11</CLanguageStandard> | |||
<CppLanguageStandard>c++1y</CppLanguageStandard> | |||
<DisableSpecificWarnings>4834</DisableSpecificWarnings> | |||
<EnableModules>true</EnableModules> | |||
</ClCompile> | |||
<Link> | |||
<SubSystem>Console</SubSystem> | |||
@@ -150,20 +151,15 @@ | |||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | |||
<ClCompile> | |||
<WarningLevel>Level4</WarningLevel> | |||
<Optimization>MaxSpeed</Optimization> | |||
<FunctionLevelLinking>true</FunctionLevelLinking> | |||
<Optimization>Full</Optimization> | |||
<IntrinsicFunctions>true</IntrinsicFunctions> | |||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;ASIO_STANDALONE;RESUMEF_ENABLE_MULT_SCHEDULER=1;_SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING=1;ASIO_DISABLE_CONCEPTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||
<AdditionalIncludeDirectories>..\librf;..\..\asio\asio\include;..\..\asio-1.10.6\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |||
<AdditionalOptions>/await</AdditionalOptions> | |||
<ExceptionHandling>Sync</ExceptionHandling> | |||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> | |||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> | |||
<OmitFramePointers>true</OmitFramePointers> | |||
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations> | |||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed> | |||
<StringPooling>true</StringPooling> | |||
<LanguageStandard>stdcpp17</LanguageStandard> | |||
<BufferSecurityCheck>false</BufferSecurityCheck> | |||
<LanguageStandard>stdcpplatest</LanguageStandard> | |||
<MultiProcessorCompilation>true</MultiProcessorCompilation> | |||
<SDLCheck> | |||
</SDLCheck> | |||
@@ -198,6 +194,7 @@ | |||
<ClCompile Include="..\tutorial\test_async_event.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_event_timeout.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_exception.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_memory_layout.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_modern_cb.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_multi_thread.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_mutex.cpp" /> | |||
@@ -225,7 +222,6 @@ | |||
<ClInclude Include="..\librf\src\future.h" /> | |||
<ClInclude Include="..\librf\src\generator.h" /> | |||
<ClInclude Include="..\librf\src\promise.h" /> | |||
<ClInclude Include="..\librf\src\task_list.h" /> | |||
<ClInclude Include="..\librf\src\mutex.h" /> | |||
<ClInclude Include="..\librf\src\rf_task.h" /> | |||
<ClInclude Include="..\librf\src\scheduler.h" /> |
@@ -109,6 +109,9 @@ | |||
<ClCompile Include="..\benchmark\benchmark_channel_passing_next.cpp"> | |||
<Filter>benchmark</Filter> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_memory_layout.cpp"> | |||
<Filter>tutorial</Filter> | |||
</ClCompile> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ClInclude Include="..\librf\librf.h"> | |||
@@ -165,9 +168,6 @@ | |||
<ClInclude Include="..\librf\src\when.h"> | |||
<Filter>librf\src</Filter> | |||
</ClInclude> | |||
<ClInclude Include="..\librf\src\task_list.h"> | |||
<Filter>librf\src</Filter> | |||
</ClInclude> | |||
<ClInclude Include="..\librf\src\promise.h"> | |||
<Filter>librf\src</Filter> | |||
</ClInclude> |