Browse Source

增加测试内存布局的范例

tags/v2.9.7
tearshark 4 years ago
parent
commit
3badb4e13f

+ 0
- 3
benchmark/benchmark_async_mem.cpp View File

{ {
using namespace std::chrono; 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) for (size_t i = 0; i < N; ++i)
{ {
go[=]()->resumef::future_t<size_t> go[=]()->resumef::future_t<size_t>

+ 8
- 0
librf/src/generator.h View File

_Alloc_char _Al; _Alloc_char _Al;
char* ptr = _Al.allocate(_Size + _State_size); 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; return ptr + _State_size;
} }

+ 14
- 12
librf/src/promise.h View File

using promise_type = promise_t<value_type>; using promise_type = promise_t<value_type>;
using future_type = future_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(promise_impl_t&& _Right) noexcept = default;
promise_impl_t& operator = (promise_impl_t&& _Right) noexcept = default; promise_impl_t& operator = (promise_impl_t&& _Right) noexcept = default;
promise_impl_t(const promise_impl_t&) = delete; promise_impl_t(const promise_impl_t&) = delete;
{ {
size_t _State_size = _Align_size<state_type>(); size_t _State_size = _Align_size<state_type>();
assert(_Size >= sizeof(uint32_t) && _Size < (std::numeric_limits<uint32_t>::max)() - sizeof(_State_size)); 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; _Alloc_char _Al;
char* ptr = _Al.allocate(_Size + _State_size); 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; 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>(); size_t _State_size = _Align_size<state_type>();
assert(_Size >= sizeof(uint32_t) && _Size < (std::numeric_limits<uint32_t>::max)() - sizeof(_State_size)); assert(_Size >= sizeof(uint32_t) && _Size < (std::numeric_limits<uint32_t>::max)() - sizeof(_State_size));


_Alloc_char _Al; _Alloc_char _Al;
state_type* st = reinterpret_cast<state_type*>(static_cast<char*>(_Ptr) - _State_size); 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(); st->unlock();
} }
}; };

+ 6
- 6
librf/src/state.h View File

{ {
return _parent; 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); void set_exception(std::exception_ptr e);
using state_future_t::lock_type; using state_future_t::lock_type;
using value_type = _Ty; 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) explicit state_t(bool awaitor) :state_future_t(awaitor)
{ {
{ {
using state_future_t::lock_type; 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) explicit state_t(bool awaitor) :state_future_t(awaitor)
{ {

+ 1
- 1
tutorial/test_async_cb.cpp View File

using namespace resumef; using namespace resumef;
template<class _Ctype> 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; using namespace std::chrono;
std::thread([val, cb = std::forward<_Ctype>(cb)] std::thread([val, cb = std::forward<_Ctype>(cb)]

+ 139
- 0
tutorial/test_async_memory_layout.cpp View File


#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;
}

+ 0
- 11
tutorial/test_async_routine.cpp View File

{ {
using namespace std::chrono; 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) for (size_t i = 0; i < 3; ++i)
{ {
co_await resumef::sleep_for(100ms); co_await resumef::sleep_for(100ms);

+ 3
- 1
vs_proj/librf.cpp View File

extern void resumable_main_multi_thread(); extern void resumable_main_multi_thread();
extern void resumable_main_channel_mult_thread(); extern void resumable_main_channel_mult_thread();
extern void resumable_main_when_all(); extern void resumable_main_when_all();
extern void resumable_main_layout();
extern void resumable_main_benchmark_mem(); extern void resumable_main_benchmark_mem();
extern void benchmark_main_channel_passing_next(); extern void benchmark_main_channel_passing_next();
{ {
(void)argc; (void)argc;
(void)argv; (void)argv;
resumable_main_yield_return();
resumable_main_layout();
//if (argc > 1) //if (argc > 1)
// resumable_main_benchmark_asio_client(atoi(argv[1])); // resumable_main_benchmark_asio_client(atoi(argv[1]));
// resumable_main_benchmark_asio_server(); // resumable_main_benchmark_asio_server();
//resumable_main_cb(); //resumable_main_cb();
//resumable_main_layout();
//resumable_main_modern_cb(); //resumable_main_modern_cb();
//resumable_main_suspend_always(); //resumable_main_suspend_always();
//resumable_main_yield_return(); //resumable_main_yield_return();

+ 9
- 13
vs_proj/librf.vcxproj View File

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>NotSet</CharacterSet> <CharacterSet>NotSet</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet> <CharacterSet>NotSet</CharacterSet>
</PropertyGroup> </PropertyGroup>
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <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> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\librf;..\..\asio\asio\include;..\..\asio-1.10.6\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\librf;..\..\asio\asio\include;..\..\asio-1.10.6\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/await</AdditionalOptions> <AdditionalOptions>/await</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpp17</LanguageStandard>
<LanguageStandard>stdcpplatest</LanguageStandard>
<MinimalRebuild /> <MinimalRebuild />
<CLanguageStandard>c11</CLanguageStandard> <CLanguageStandard>c11</CLanguageStandard>
<CppLanguageStandard>c++1y</CppLanguageStandard> <CppLanguageStandard>c++1y</CppLanguageStandard>
<DisableSpecificWarnings>4834</DisableSpecificWarnings> <DisableSpecificWarnings>4834</DisableSpecificWarnings>
<EnableModules>true</EnableModules>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<Optimization>Full</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions> <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> <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> <AdditionalIncludeDirectories>..\librf;..\..\asio\asio\include;..\..\asio-1.10.6\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/await</AdditionalOptions> <AdditionalOptions>/await</AdditionalOptions>
<ExceptionHandling>Sync</ExceptionHandling> <ExceptionHandling>Sync</ExceptionHandling>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<StringPooling>true</StringPooling> <StringPooling>true</StringPooling>
<LanguageStandard>stdcpp17</LanguageStandard>
<BufferSecurityCheck>false</BufferSecurityCheck>
<LanguageStandard>stdcpplatest</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<SDLCheck> <SDLCheck>
</SDLCheck> </SDLCheck>
<ClCompile Include="..\tutorial\test_async_event.cpp" /> <ClCompile Include="..\tutorial\test_async_event.cpp" />
<ClCompile Include="..\tutorial\test_async_event_timeout.cpp" /> <ClCompile Include="..\tutorial\test_async_event_timeout.cpp" />
<ClCompile Include="..\tutorial\test_async_exception.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_modern_cb.cpp" />
<ClCompile Include="..\tutorial\test_async_multi_thread.cpp" /> <ClCompile Include="..\tutorial\test_async_multi_thread.cpp" />
<ClCompile Include="..\tutorial\test_async_mutex.cpp" /> <ClCompile Include="..\tutorial\test_async_mutex.cpp" />
<ClInclude Include="..\librf\src\future.h" /> <ClInclude Include="..\librf\src\future.h" />
<ClInclude Include="..\librf\src\generator.h" /> <ClInclude Include="..\librf\src\generator.h" />
<ClInclude Include="..\librf\src\promise.h" /> <ClInclude Include="..\librf\src\promise.h" />
<ClInclude Include="..\librf\src\task_list.h" />
<ClInclude Include="..\librf\src\mutex.h" /> <ClInclude Include="..\librf\src\mutex.h" />
<ClInclude Include="..\librf\src\rf_task.h" /> <ClInclude Include="..\librf\src\rf_task.h" />
<ClInclude Include="..\librf\src\scheduler.h" /> <ClInclude Include="..\librf\src\scheduler.h" />

+ 3
- 3
vs_proj/librf.vcxproj.filters View File

<ClCompile Include="..\benchmark\benchmark_channel_passing_next.cpp"> <ClCompile Include="..\benchmark\benchmark_channel_passing_next.cpp">
<Filter>benchmark</Filter> <Filter>benchmark</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\tutorial\test_async_memory_layout.cpp">
<Filter>tutorial</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\librf\librf.h"> <ClInclude Include="..\librf\librf.h">
<ClInclude Include="..\librf\src\when.h"> <ClInclude Include="..\librf\src\when.h">
<Filter>librf\src</Filter> <Filter>librf\src</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\librf\src\task_list.h">
<Filter>librf\src</Filter>
</ClInclude>
<ClInclude Include="..\librf\src\promise.h"> <ClInclude Include="..\librf\src\promise.h">
<Filter>librf\src</Filter> <Filter>librf\src</Filter>
</ClInclude> </ClInclude>

Loading…
Cancel
Save