#include "librf.h" | #include "librf.h" | ||||
const size_t N = 1000000; | |||||
const size_t N = 10000000; | |||||
const size_t LOOP_COUNT = 100; | const size_t LOOP_COUNT = 100; | ||||
volatile size_t globalValue = 0; | volatile size_t globalValue = 0; |
bool state_future_t::is_ready() const | bool state_future_t::is_ready() const | ||||
{ | { | ||||
scoped_lock<lock_type> __guard(this->_mtx); | scoped_lock<lock_type> __guard(this->_mtx); | ||||
return _exception != nullptr || _has_value || !_is_awaitor; | |||||
return _exception != nullptr || _has_value.load(std::memory_order_acquire) || !_is_awaitor; | |||||
} | } | ||||
void state_future_t::set_exception(std::exception_ptr e) | void state_future_t::set_exception(std::exception_ptr e) | ||||
if (this->_exception) | if (this->_exception) | ||||
std::rethrow_exception(std::move(this->_exception)); | std::rethrow_exception(std::move(this->_exception)); | ||||
if (!this->_has_value) | |||||
if (!this->_has_value.load(std::memory_order_acquire)) | |||||
std::rethrow_exception(std::make_exception_ptr(future_exception{error_code::not_ready})); | std::rethrow_exception(std::make_exception_ptr(future_exception{error_code::not_ready})); | ||||
} | } | ||||
{ | { | ||||
{ | { | ||||
scoped_lock<lock_type> __guard(this->_mtx); | scoped_lock<lock_type> __guard(this->_mtx); | ||||
this->_has_value = true; | |||||
this->_has_value.store(true, std::memory_order_release); | |||||
} | } | ||||
scheduler_t* sch = this->get_scheduler(); | scheduler_t* sch = this->get_scheduler(); |
#endif | #endif | ||||
std::exception_ptr _exception; | std::exception_ptr _exception; | ||||
uint32_t _alloc_size; | uint32_t _alloc_size; | ||||
bool _has_value = false; | |||||
std::atomic<bool> _has_value{ false }; | |||||
bool _is_awaitor; | bool _is_awaitor; | ||||
initor_type _is_initor = initor_type::None; | initor_type _is_initor = initor_type::None; | ||||
public: | public: | ||||
void future_await_suspend(coroutine_handle<_PromiseT> handler); | void future_await_suspend(coroutine_handle<_PromiseT> handler); | ||||
bool future_await_ready() | bool future_await_ready() | ||||
{ | { | ||||
scoped_lock<lock_type> __guard(this->_mtx); | |||||
return _has_value; | |||||
//scoped_lock<lock_type> __guard(this->_mtx); | |||||
return _has_value.load(std::memory_order_acquire); | |||||
} | } | ||||
template<class _PromiseT, typename = std::enable_if_t<is_promise_v<_PromiseT>>> | template<class _PromiseT, typename = std::enable_if_t<is_promise_v<_PromiseT>>> | ||||
public: | public: | ||||
~state_t() | ~state_t() | ||||
{ | { | ||||
if (_has_value) | |||||
if (_has_value.load(std::memory_order_acquire)) | |||||
cast_value_ptr()->~value_type(); | cast_value_ptr()->~value_type(); | ||||
} | } | ||||
this->_coro = handler; | this->_coro = handler; | ||||
} | } | ||||
this->_has_value = true; | |||||
this->_has_value.store(true, std::memory_order_release); | |||||
} | } | ||||
if (!handler.done()) | if (!handler.done()) | ||||
this->_coro = handler; | this->_coro = handler; | ||||
} | } | ||||
if (this->_has_value) | |||||
if (this->_has_value.load(std::memory_order_acquire)) | |||||
{ | { | ||||
*this->cast_value_ptr() = std::forward<U>(val); | *this->cast_value_ptr() = std::forward<U>(val); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
new (this->cast_value_ptr()) value_type(std::forward<U>(val)); | new (this->cast_value_ptr()) value_type(std::forward<U>(val)); | ||||
this->_has_value = true; | |||||
this->_has_value.store(true, std::memory_order_release); | |||||
} | } | ||||
} | } | ||||
scoped_lock<lock_type> __guard(this->_mtx); | scoped_lock<lock_type> __guard(this->_mtx); | ||||
if (this->_exception) | if (this->_exception) | ||||
std::rethrow_exception(std::move(this->_exception)); | std::rethrow_exception(std::move(this->_exception)); | ||||
if (!this->_has_value) | |||||
if (!this->_has_value.load(std::memory_order_acquire)) | |||||
std::rethrow_exception(std::make_exception_ptr(future_exception{error_code::not_ready})); | std::rethrow_exception(std::make_exception_ptr(future_exception{error_code::not_ready})); | ||||
return std::move(*this->cast_value_ptr()); | return std::move(*this->cast_value_ptr()); | ||||
{ | { | ||||
scoped_lock<lock_type> __guard(this->_mtx); | scoped_lock<lock_type> __guard(this->_mtx); | ||||
if (this->_has_value) | |||||
if (this->_has_value.load(std::memory_order_acquire)) | |||||
{ | { | ||||
*this->cast_value_ptr() = std::forward<U>(val); | *this->cast_value_ptr() = std::forward<U>(val); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
new (this->cast_value_ptr()) value_type(std::forward<U>(val)); | new (this->cast_value_ptr()) value_type(std::forward<U>(val)); | ||||
this->_has_value = true; | |||||
this->_has_value.store(true, std::memory_order_release); | |||||
} | } | ||||
} | } | ||||
{ | { | ||||
(void)argc; | (void)argc; | ||||
(void)argv; | (void)argv; | ||||
//resumable_main_layout(); | |||||
//return 0; | |||||
resumable_main_layout(); | |||||
return 0; | |||||
//if (argc > 1) | //if (argc > 1) | ||||
// resumable_main_benchmark_asio_client(atoi(argv[1])); | // resumable_main_benchmark_asio_client(atoi(argv[1])); |