Browse Source

增加测试内存布局的范例

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

+ 0
- 3
benchmark/benchmark_async_mem.cpp View File

@@ -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>

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

@@ -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
- 12
librf/src/promise.h View File

@@ -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();
}
};

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

@@ -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)
{

+ 1
- 1
tutorial/test_async_cb.cpp View File

@@ -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)]

+ 139
- 0
tutorial/test_async_memory_layout.cpp View File

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

+ 0
- 11
tutorial/test_async_routine.cpp View File

@@ -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);

+ 3
- 1
vs_proj/librf.cpp View File

@@ -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();

+ 9
- 13
vs_proj/librf.vcxproj View File

@@ -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" />

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

@@ -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>

Loading…
Cancel
Save