#include "librf.h" | #include "librf.h" | ||||
const size_t N = 5000000; | |||||
const size_t N = 2000000; | |||||
const size_t LOOP_COUNT = 50; | const size_t LOOP_COUNT = 50; | ||||
volatile size_t globalValue = 0; | volatile size_t globalValue = 0; |
template<typename Allocator> | template<typename Allocator> | ||||
promise_handler(const rf_task_t<Allocator> &) | promise_handler(const rf_task_t<Allocator> &) | ||||
: state_(resumef::make_counted<state_type>(true)) | |||||
: state_(state_type::typename _Alloc_state<state_type>(true)) | |||||
{ | { | ||||
} | } | ||||
template<typename Allocator> | template<typename Allocator> | ||||
promise_handler(const rf_task_t<Allocator> &) | promise_handler(const rf_task_t<Allocator> &) | ||||
: state_(resumef::make_counted<state_type>(true)) | |||||
: state_(state_type::typename _Alloc_state<state_type>(true)) | |||||
{ | { | ||||
} | } | ||||
typedef resumef::state_t<result_type> state_type; | typedef resumef::state_t<result_type> state_type; | ||||
promise_handler_base() | promise_handler_base() | ||||
: state_(resumef::make_counted<state_type>(true)) | |||||
: state_(resumef::state_future_t::_Alloc_state<state_type>(true)) | |||||
{ | { | ||||
} | } | ||||
T* _p = nullptr; | T* _p = nullptr; | ||||
}; | }; | ||||
template <typename T, typename... Args> | |||||
counted_ptr<T> make_counted(Args&&... args) | |||||
{ | |||||
return new T{std::forward<Args>(args)...}; | |||||
} | |||||
template <typename T, typename U> | template <typename T, typename U> | ||||
inline bool operator == (const counted_ptr<T>& _Left, const counted_ptr<U>& _Right) | inline bool operator == (const counted_ptr<T>& _Left, const counted_ptr<U>& _Right) | ||||
{ | { |
//在初始地址上构造state | //在初始地址上构造state | ||||
{ | { | ||||
state_type* st = new(ptr) state_type(); | |||||
state_type* st = state_type::_Construct(ptr); | |||||
st->lock(); | st->lock(); | ||||
} | } | ||||
//在初始地址上构造state | //在初始地址上构造state | ||||
{ | { | ||||
state_type* st = new(ptr) state_type(_Size + _State_size); | |||||
state_type* st = state_future_t::_Construct<state_type>(ptr, _Size + _State_size); | |||||
st->lock(); | st->lock(); | ||||
} | } | ||||
_Alloc_char _Al; | _Alloc_char _Al; | ||||
return _Al.deallocate(reinterpret_cast<char*>(this), _Size); | return _Al.deallocate(reinterpret_cast<char*>(this), _Size); | ||||
} | } | ||||
state_generator_t* state_generator_t::_Alloc_state() | |||||
{ | |||||
_Alloc_char _Al; | |||||
size_t _Size = _Align_size<state_generator_t>(); | |||||
#if RESUMEF_DEBUG_COUNTER | |||||
std::cout << "state_generator_t::alloc, size=" << sizeof(state_generator_t) << std::endl; | |||||
#endif | |||||
char* _Ptr = _Al.allocate(_Size); | |||||
return new(_Ptr) state_generator_t(); | |||||
} | |||||
void state_generator_t::destroy_deallocate() | void state_generator_t::destroy_deallocate() | ||||
{ | { | ||||
size_t _Size = _Align_size<state_generator_t>(); | size_t _Size = _Align_size<state_generator_t>(); |
{ | { | ||||
private: | private: | ||||
virtual void destroy_deallocate() override; | virtual void destroy_deallocate() override; | ||||
state_generator_t() = default; | |||||
public: | public: | ||||
virtual void resume() override; | virtual void resume() override; | ||||
virtual bool has_handler() const noexcept override; | virtual bool has_handler() const noexcept override; | ||||
_coro = handler; | _coro = handler; | ||||
} | } | ||||
static state_generator_t * _Alloc_state() | |||||
#if RESUMEF_INLINE_STATE | |||||
static state_generator_t* _Construct(void* _Ptr) | |||||
{ | { | ||||
_Alloc_char _Al; | |||||
size_t _Size = sizeof(state_generator_t); | |||||
#if RESUMEF_DEBUG_COUNTER | |||||
std::cout << "state_generator_t::alloc, size=" << sizeof(state_generator_t) << std::endl; | |||||
#endif | |||||
char* _Ptr = _Al.allocate(_Size); | |||||
return new(_Ptr) state_generator_t(); | return new(_Ptr) state_generator_t(); | ||||
} | } | ||||
#endif | |||||
static state_generator_t* _Alloc_state(); | |||||
}; | }; | ||||
struct state_future_t : public state_base_t | struct state_future_t : public state_base_t | ||||
static_assert(alignof(bool) == 1); | static_assert(alignof(bool) == 1); | ||||
static_assert(sizeof(std::atomic<initor_type>) == 1); | static_assert(sizeof(std::atomic<initor_type>) == 1); | ||||
static_assert(alignof(std::atomic<initor_type>) == 1); | static_assert(alignof(std::atomic<initor_type>) == 1); | ||||
public: | |||||
state_future_t() | |||||
{ | |||||
#if RESUMEF_DEBUG_COUNTER | |||||
_id = ++g_resumef_state_id; | |||||
#endif | |||||
_is_future = true; | |||||
} | |||||
protected: | |||||
explicit state_future_t(bool awaitor) | explicit state_future_t(bool awaitor) | ||||
{ | { | ||||
#if RESUMEF_DEBUG_COUNTER | #if RESUMEF_DEBUG_COUNTER | ||||
#endif | #endif | ||||
_is_future = !awaitor; | _is_future = !awaitor; | ||||
} | } | ||||
public: | |||||
virtual void destroy_deallocate() override; | virtual void destroy_deallocate() override; | ||||
virtual void resume() override; | virtual void resume() override; | ||||
virtual bool has_handler() const noexcept override; | virtual bool has_handler() const noexcept override; | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | ||||
void promise_final_suspend(coroutine_handle<_PromiseT> handler); | void promise_final_suspend(coroutine_handle<_PromiseT> handler); | ||||
#if RESUMEF_INLINE_STATE | |||||
template<class _Sty> | |||||
static _Sty* _Construct(void* _Ptr, size_t _Size) | |||||
{ | |||||
_Sty* st = new(_Ptr) _Sty(false); | |||||
st->_alloc_size = _Size; | |||||
return st; | |||||
} | |||||
#endif | |||||
template<class _Sty> | template<class _Sty> | ||||
static inline _Sty* _Alloc_state(bool awaitor) | static inline _Sty* _Alloc_state(bool awaitor) | ||||
{ | { | ||||
_Alloc_char _Al; | _Alloc_char _Al; | ||||
size_t _Size = sizeof(_Sty); | |||||
size_t _Size = _Align_size<_Sty>(); | |||||
#if RESUMEF_DEBUG_COUNTER | #if RESUMEF_DEBUG_COUNTER | ||||
std::cout << "state_future_t::alloc, size=" << _Size << std::endl; | std::cout << "state_future_t::alloc, size=" << _Size << std::endl; | ||||
#endif | #endif | ||||
char* _Ptr = _Al.allocate(_Size); | char* _Ptr = _Al.allocate(_Size); | ||||
return new(_Ptr) _Sty(awaitor); | |||||
_Sty* st = new(_Ptr) _Sty(awaitor); | |||||
st->_alloc_size = _Size; | |||||
return st; | |||||
} | } | ||||
}; | }; | ||||
using state_future_t::lock_type; | using state_future_t::lock_type; | ||||
using value_type = _Ty; | using value_type = _Ty; | ||||
explicit state_t(size_t alloc_size) :state_future_t() | |||||
{ | |||||
_alloc_size = static_cast<uint32_t>(alloc_size); | |||||
} | |||||
explicit state_t(bool awaitor) :state_future_t(awaitor) | |||||
{ | |||||
_alloc_size = sizeof(*this); | |||||
} | |||||
private: | |||||
explicit state_t(bool awaitor) :state_future_t(awaitor) {} | |||||
public: | public: | ||||
~state_t() | ~state_t() | ||||
{ | { | ||||
using state_future_t::lock_type; | using state_future_t::lock_type; | ||||
using value_type = _Ty; | using value_type = _Ty; | ||||
using reference_type = _Ty&; | using reference_type = _Ty&; | ||||
explicit state_t(size_t alloc_size) :state_future_t() | |||||
{ | |||||
_alloc_size = static_cast<uint32_t>(alloc_size); | |||||
} | |||||
explicit state_t(bool awaitor) :state_future_t(awaitor) | |||||
{ | |||||
_alloc_size = sizeof(*this); | |||||
} | |||||
private: | |||||
explicit state_t(bool awaitor) :state_future_t(awaitor) {} | |||||
public: | public: | ||||
~state_t() | ~state_t() | ||||
{ | { | ||||
{ | { | ||||
friend state_future_t; | friend state_future_t; | ||||
using state_future_t::lock_type; | using state_future_t::lock_type; | ||||
explicit state_t(size_t alloc_size) :state_future_t() | |||||
{ | |||||
_alloc_size = static_cast<uint32_t>(alloc_size); | |||||
} | |||||
explicit state_t(bool awaitor) :state_future_t(awaitor) | |||||
{ | |||||
_alloc_size = sizeof(*this); | |||||
} | |||||
private: | |||||
explicit state_t(bool awaitor) :state_future_t(awaitor) {} | |||||
public: | public: | ||||
void future_await_resume(); | void future_await_resume(); | ||||
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> | template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>> |
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | ||||
<ConfigurationType>Application</ConfigurationType> | <ConfigurationType>Application</ConfigurationType> | ||||
<PlatformToolset>ClangCL</PlatformToolset> | |||||
<PlatformToolset>v142</PlatformToolset> | |||||
<UseDebugLibraries>true</UseDebugLibraries> | <UseDebugLibraries>true</UseDebugLibraries> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | ||||
<ConfigurationType>Application</ConfigurationType> | <ConfigurationType>Application</ConfigurationType> | ||||
<UseDebugLibraries>false</UseDebugLibraries> | <UseDebugLibraries>false</UseDebugLibraries> | ||||
<PlatformToolset>ClangCL</PlatformToolset> | |||||
<PlatformToolset>v142</PlatformToolset> | |||||
<WholeProgramOptimization>true</WholeProgramOptimization> | <WholeProgramOptimization>true</WholeProgramOptimization> | ||||
<CharacterSet>NotSet</CharacterSet> | <CharacterSet>NotSet</CharacterSet> | ||||
<EnableASAN>true</EnableASAN> | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | ||||
<ConfigurationType>Application</ConfigurationType> | <ConfigurationType>Application</ConfigurationType> | ||||
<PlatformToolset>ClangCL</PlatformToolset> | |||||
<PlatformToolset>v142</PlatformToolset> | |||||
<UseDebugLibraries>true</UseDebugLibraries> | <UseDebugLibraries>true</UseDebugLibraries> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> |