Browse Source

优化一点内存占用空间和性能

更好的兼容clang
版本升级到2.2.1
tags/v2.9.7
tearshark 4 years ago
parent
commit
3ba9a56cae

+ 1
- 1
benchmark/benchmark_asio_echo.cpp View File

{ {
auto self = this->shared_from_this(); auto self = this->shared_from_this();
asio::async_connect(socket_, endpoint_, asio::async_connect(socket_, endpoint_,
[this, self](std::error_code ec, tcp::resolver::iterator iter)
[this, self](std::error_code ec, tcp::resolver::iterator )
{ {
if (!ec) if (!ec)
{ {

+ 1
- 1
benchmark/benchmark_async_mem.cpp View File

for (size_t i = 0; i < N; ++i) for (size_t i = 0; i < N; ++i)
{ {
go[=]()->resumef::future_t<size_t>
go[=]()->resumef::generator_t<size_t>
{ {
for (size_t k = 0; k < 10; ++k) for (size_t k = 0; k < 10; ++k)
{ {

+ 3
- 2
librf/src/awaitable.h View File

using typename awaitable_impl_t<_Ty>::value_type; using typename awaitable_impl_t<_Ty>::value_type;
using awaitable_impl_t<_Ty>::awaitable_impl_t; using awaitable_impl_t<_Ty>::awaitable_impl_t;


void set_value(value_type value) const
template<class U>
void set_value(U&& value) const
{ {
this->_state->set_value(std::move(value));
this->_state->set_value(std::forward<U>(value));
this->_state = nullptr; this->_state = nullptr;
} }
}; };

+ 1
- 1
librf/src/def.h View File

#pragma once #pragma once
#define LIB_RESUMEF_VERSION 20200 // 2.2.0
#define LIB_RESUMEF_VERSION 20201 // 2.2.1
#if defined(RESUMEF_MODULE_EXPORT) #if defined(RESUMEF_MODULE_EXPORT)
#define RESUMEF_NS export namespace resumef #define RESUMEF_NS export namespace resumef

+ 17
- 0
librf/src/future.h View File

}; };
} }
namespace std {
namespace experimental {
/*If the coroutine is defined as task<float> foo(std::string x, bool flag);,
then its Promise type is std::coroutine_traits<task<float>, std::string, bool>::promise_type.
If the coroutine is a non-static member function, such as task<void> my_class::method1(int x) const;,
its Promise type is std::coroutine_traits<task<void>, const my_class&, int>::promise_type.
*/
template <typename _Ty, typename... Args>
struct coroutine_traits<resumef::future_t<_Ty>, Args...>
{
typedef resumef::promise_t<_Ty> promise_type;
};
}
} // namespace std::experimental

+ 30
- 10
librf/src/generator.h View File

} }
promise_type(promise_type&& _Right) noexcept = default; promise_type(promise_type&& _Right) noexcept = default;
promise_type& operator = (promise_type&& _Right) noexcept = default; promise_type& operator = (promise_type&& _Right) noexcept = default;
promise_type(const promise_type&) = delete;
promise_type& operator = (const promise_type&) = delete;
promise_type(const promise_type&) = default;
promise_type& operator = (const promise_type&) = default;
promise_type& get_return_object()
generator_t get_return_object()
{ {
return *this;
return generator_t{ *this };
} }
bool initial_suspend() bool initial_suspend()
{ {
return (true);
return true;
} }
bool final_suspend() bool final_suspend()
{ {
return (true);
return true;
} }
void yield_value(_Ty const& _Value) void yield_value(_Ty const& _Value)
_CurrentValue = std::addressof(_Value); _CurrentValue = std::addressof(_Value);
} }
template<class = std::enable_if_t<!std::is_same_v<_Ty, void>, _Ty>>
//template<class = std::enable_if_t<!std::is_same_v<_Ty, void>, _Ty>>
void return_value(_Ty const& _Value) void return_value(_Ty const& _Value)
{ {
_CurrentValue = std::addressof(_Value); _CurrentValue = std::addressof(_Value);
} }
template<class = std::enable_if_t<std::is_same_v<_Ty, void>, _Ty>>
//template<class = std::enable_if_t<std::is_same_v<_Ty, void>, _Ty>>
void return_value() void return_value()
{ {
_CurrentValue = nullptr; _CurrentValue = nullptr;
} }
void set_exception(std::exception_ptr e)
{
std::terminate();
}
#ifdef __clang__
void unhandled_exception()
{
std::terminate();
}
#endif
template <typename _Uty> template <typename _Uty>
_Uty&& await_transform(_Uty&& _Whatever) _Uty&& await_transform(_Uty&& _Whatever)
{ {
*reinterpret_cast<uint32_t*>(_Ptr) = static_cast<uint32_t>(_Size + _State_size); *reinterpret_cast<uint32_t*>(_Ptr) = static_cast<uint32_t>(_Size + _State_size);
_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->unlock(); st->unlock();
} }
generator_t() = default; generator_t() = default;
generator_t(generator_t const&) = delete; generator_t(generator_t const&) = delete;
generator_t& operator=(generator_t const&) = delete; generator_t& operator=(generator_t const&) = delete;
generator_t(generator_t&& right_) noexcept generator_t(generator_t&& right_) noexcept
#pragma pop_macro("new") #pragma pop_macro("new")
#pragma pack(pop) #pragma pack(pop)
namespace std {
namespace experimental {
template <typename _Ty, typename _Alloc, typename... Args>
struct coroutine_traits<resumef::generator_t<_Ty, _Alloc>, Args...>
{
typedef typename resumef::generator_t<_Ty, _Alloc>::promise_type promise_type;
};
}
} // namespace std::experimental

+ 11
- 5
librf/src/promise.h View File

suspend_on_final final_suspend() noexcept; suspend_on_final final_suspend() noexcept;
void set_exception(std::exception_ptr e); void set_exception(std::exception_ptr e);
#ifdef __clang__ #ifdef __clang__
void unhandled_exception();
void unhandled_exception(); //If the coroutine ends with an uncaught exception, it performs the following:
#endif #endif
future_type get_return_object(); future_type get_return_object();
void cancellation_requested(); void cancellation_requested();
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;
/*If allocation fails, the coroutine throws std::bad_alloc,
unless the Promise type defines the member function Promise::get_return_object_on_allocation_failure().
If that member function is defined, allocation uses the nothrow form of operator new and on allocation failure,
the coroutine immediately returns the object obtained from Promise::get_return_object_on_allocation_failure() to the caller.
*/
char* ptr = _Al.allocate(_Size + _State_size); char* ptr = _Al.allocate(_Size + _State_size);
#if RESUMEF_DEBUG_COUNTER #if RESUMEF_DEBUG_COUNTER
std::cout << " future_promise::new, alloc size=" << (_Size + _State_size) << std::endl; std::cout << " future_promise::new, alloc size=" << (_Size + _State_size) << std::endl;
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;
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->unlock(); st->unlock();
} }
using typename promise_impl_t<_Ty>::value_type; using typename promise_impl_t<_Ty>::value_type;
using promise_impl_t<_Ty>::get_return_object; using promise_impl_t<_Ty>::get_return_object;


void return_value(value_type val);
void yield_value(value_type val);
template<class U>
void return_value(U&& val); //co_return val
template<class U>
void yield_value(U&& val);
}; };


template<> template<>
{ {
using promise_impl_t<void>::get_return_object; using promise_impl_t<void>::get_return_object;


void return_void();
void return_void(); //co_return;
void yield_value(); void yield_value();
}; };



+ 19
- 13
librf/src/promise.inl View File

 
RESUMEF_NS RESUMEF_NS
{ {
/*
Note: the awaiter object is part of coroutine state (as a temporary whose lifetime crosses a suspension point)
and is destroyed before the co_await expression finishes.
It can be used to maintain per-operation state as required by some async I/O APIs without resorting to additional heap allocations.
*/

struct suspend_on_initial struct suspend_on_initial
{ {
state_future_t* _state;

inline bool await_ready() noexcept inline bool await_ready() noexcept
{ {
return false; return false;
template<class _PromiseT, typename = std::enable_if_t<is_promise_v<_PromiseT>>> template<class _PromiseT, typename = std::enable_if_t<is_promise_v<_PromiseT>>>
inline void await_suspend(coroutine_handle<_PromiseT> handler) noexcept inline void await_suspend(coroutine_handle<_PromiseT> handler) noexcept
{ {
_PromiseT& promise = handler.promise();
auto* _state = promise.get_state();
_state->promise_initial_suspend(handler); _state->promise_initial_suspend(handler);
} }
inline void await_resume() noexcept inline void await_resume() noexcept
{ {
_state->promise_await_resume();
} }
}; };
struct suspend_on_final struct suspend_on_final
{ {
state_future_t* _state;

inline bool await_ready() noexcept inline bool await_ready() noexcept
{ {
return false; return false;
template<class _PromiseT, typename = std::enable_if_t<is_promise_v<_PromiseT>>> template<class _PromiseT, typename = std::enable_if_t<is_promise_v<_PromiseT>>>
inline void await_suspend(coroutine_handle<_PromiseT> handler) noexcept inline void await_suspend(coroutine_handle<_PromiseT> handler) noexcept
{ {
_PromiseT& promise = handler.promise();
auto* _state = promise.get_state();
_state->promise_final_suspend(handler); _state->promise_final_suspend(handler);
} }
inline void await_resume() noexcept inline void await_resume() noexcept
{ {
_state->promise_await_resume();
} }
}; };


template <typename _Ty> template <typename _Ty>
inline suspend_on_initial promise_impl_t<_Ty>::initial_suspend() noexcept inline suspend_on_initial promise_impl_t<_Ty>::initial_suspend() noexcept
{ {
return { this->get_state() };
return {};
} }


template <typename _Ty> template <typename _Ty>
inline suspend_on_final promise_impl_t<_Ty>::final_suspend() noexcept inline suspend_on_final promise_impl_t<_Ty>::final_suspend() noexcept
{ {
return { this->get_state() };
return {};
} }


template <typename _Ty> template <typename _Ty>
template <typename _Ty> template <typename _Ty>
inline void promise_impl_t<_Ty>::unhandled_exception() inline void promise_impl_t<_Ty>::unhandled_exception()
{ {
std::terminate();
this->get_state()->set_exception(std::current_exception());
} }
#endif #endif






template<class _Ty> template<class _Ty>
inline void promise_t<_Ty>::return_value(value_type val)
template<class U>
inline void promise_t<_Ty>::return_value(U&& val)
{ {
this->get_state()->set_value(std::move(val));
this->get_state()->set_value(std::forward<U>(val));
} }


template<class _Ty> template<class _Ty>
inline void promise_t<_Ty>::yield_value(value_type val)
template<class U>
inline void promise_t<_Ty>::yield_value(U&& val)
{ {
this->get_state()->promise_yield_value(this, std::move(val));
this->get_state()->promise_yield_value(this, std::forward<U>(val));
} }


inline void promise_t<void>::return_void() inline void promise_t<void>::return_void()

+ 9
- 9
librf/src/state.cpp View File

{ {
std::unique_lock<lock_type> __guard(_mtx); std::unique_lock<lock_type> __guard(_mtx);
if (_initor != nullptr && _is_initor)
if (_is_initor == initor_type::Initial)
{ {
coroutine_handle<> handler = _initor;
_initor = nullptr;
assert(_initor != nullptr);
_is_initor = initor_type::None;
__guard.unlock(); __guard.unlock();
handler.resume();
_initor.resume();
return; return;
} }
return; return;
} }
if (_initor != nullptr && !_is_initor)
if (_is_initor == initor_type::Final)
{ {
coroutine_handle<> handler = _initor;
_initor = nullptr;
_is_initor = initor_type::None;
__guard.unlock(); __guard.unlock();
handler.destroy();
_initor.destroy();
return; return;
} }
} }
bool state_future_t::has_handler() const bool state_future_t::has_handler() const
{ {
scoped_lock<lock_type> __guard(_mtx); scoped_lock<lock_type> __guard(_mtx);
return _coro != nullptr || _initor != nullptr;
return _coro != nullptr || _is_initor != initor_type::None;
} }
bool state_future_t::is_ready() const bool state_future_t::is_ready() const

+ 20
- 17
librf/src/state.h View File

struct state_future_t : public state_base_t struct state_future_t : public state_base_t
{ {
enum struct initor_type : uint8_t
{
None,
Initial,
Final
};
typedef std::recursive_mutex lock_type; typedef std::recursive_mutex lock_type;
protected: protected:
mutable lock_type _mtx; mutable lock_type _mtx;
uint32_t _alloc_size; uint32_t _alloc_size;
bool _has_value = false; bool _has_value = false;
bool _is_awaitor; bool _is_awaitor;
bool _is_initor = false;
initor_type _is_initor = initor_type::None;
public: public:
state_future_t() state_future_t()
{ {
template<class _PromiseT, typename = std::enable_if_t<is_promise_v<_PromiseT>>> template<class _PromiseT, typename = std::enable_if_t<is_promise_v<_PromiseT>>>
void promise_initial_suspend(coroutine_handle<_PromiseT> handler); void promise_initial_suspend(coroutine_handle<_PromiseT> handler);
void promise_await_resume();
template<class _PromiseT, typename = std::enable_if_t<is_promise_v<_PromiseT>>> template<class _PromiseT, typename = std::enable_if_t<is_promise_v<_PromiseT>>>
void promise_final_suspend(coroutine_handle<_PromiseT> handler); void promise_final_suspend(coroutine_handle<_PromiseT> handler);
}; };
{ {
_alloc_size = sizeof(*this); _alloc_size = sizeof(*this);
} }
private:
union union_value_type
{
value_type _value;
char _[1];
union_value_type() {}
~union_value_type() {}
};
union_value_type uv;
~state_t() ~state_t()
{ {
if (_has_value) if (_has_value)
uv._value.~value_type();
cast_value_ptr()->~value_type();
} }
public:
auto future_await_resume() -> value_type; auto future_await_resume() -> value_type;
template<class _PromiseT, typename = std::enable_if_t<is_promise_v<_PromiseT>>>
void promise_yield_value(_PromiseT* promise, value_type val);
template<class _PromiseT, typename U, typename = std::enable_if_t<is_promise_v<_PromiseT>>>
void promise_yield_value(_PromiseT* promise, U&& val);
template<typename U>
void set_value(U&& val);
private:
value_type * cast_value_ptr()
{
return static_cast<value_type*>(static_cast<void*>(_value));
}
void set_value(value_type val);
alignas(value_type) unsigned char _value[sizeof(value_type)];
}; };
template<> template<>

+ 12
- 24
librf/src/state.inl View File

template<class _PromiseT, typename _Enable> template<class _PromiseT, typename _Enable>
void state_future_t::promise_initial_suspend(coroutine_handle<_PromiseT> handler) void state_future_t::promise_initial_suspend(coroutine_handle<_PromiseT> handler)
{ {
_PromiseT& promise = handler.promise();

state_base_t* parent_state = promise.get_state();
(void)parent_state;
assert(this == parent_state);
assert(this->_scheduler == nullptr); assert(this->_scheduler == nullptr);
assert(this->_coro == nullptr); assert(this->_coro == nullptr);
this->_initor = handler;
this->_is_initor = true;
}


inline void state_future_t::promise_await_resume()
{
this->_initor = handler;
this->_is_initor = initor_type::Initial;
} }


template<class _PromiseT, typename _Enable> template<class _PromiseT, typename _Enable>
{ {
scoped_lock<lock_type> __guard(this->_mtx); scoped_lock<lock_type> __guard(this->_mtx);


_PromiseT& promise = handler.promise();

state_base_t* parent_state = promise.get_state();
(void)parent_state;
assert(this == parent_state);
this->_initor = handler; this->_initor = handler;
this->_is_initor = false;
this->_is_initor = initor_type::Final;


scheduler_t* sch = this->get_scheduler(); scheduler_t* sch = this->get_scheduler();
assert(sch != nullptr); assert(sch != nullptr);
} }


template<typename _Ty> template<typename _Ty>
template<class _PromiseT, typename _Enable >
void state_t<_Ty>::promise_yield_value(_PromiseT* promise, _Ty val)
template<class _PromiseT, typename U, typename _Enable >
void state_t<_Ty>::promise_yield_value(_PromiseT* promise, U&& val)
{ {
scoped_lock<lock_type> __guard(this->_mtx); scoped_lock<lock_type> __guard(this->_mtx);


if (this->_has_value) if (this->_has_value)
{ {
this->uv._value = std::move(val);
*this->cast_value_ptr() = std::forward<U>(val);
} }
else else
{ {
new (this->cast_value_ptr()) value_type(std::forward<U>(val));
this->_has_value = true; this->_has_value = true;
new(&this->uv._value) value_type(std::move(val));
} }


coroutine_handle<_PromiseT> handler = coroutine_handle<_PromiseT>::from_promise(*promise); coroutine_handle<_PromiseT> handler = coroutine_handle<_PromiseT>::from_promise(*promise);
if (!this->_has_value) if (!this->_has_value)
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->uv._value);
return std::move(*this->cast_value_ptr());
} }


template<typename _Ty> template<typename _Ty>
void state_t<_Ty>::set_value(value_type val)
template<typename U>
void state_t<_Ty>::set_value(U&& val)
{ {
scoped_lock<lock_type> __guard(this->_mtx); scoped_lock<lock_type> __guard(this->_mtx);


if (this->_has_value) if (this->_has_value)
{ {
this->uv._value = std::move(val);
*this->cast_value_ptr() = std::forward<U>(val);
} }
else else
{ {
new (this->cast_value_ptr()) value_type(std::forward<U>(val));
this->_has_value = true; this->_has_value = true;
new(&this->uv._value) value_type(std::move(val));
} }


scheduler_t* sch = this->get_scheduler(); scheduler_t* sch = this->get_scheduler();

+ 1
- 1
tutorial/test_async_channel.cpp View File

#endif #endif
std::cout << std::endl; std::cout << std::endl;
} }
catch (channel_exception e)
catch (resumef::channel_exception& e)
{ {
//MAX_CHANNEL_QUEUE=0,并且先读后写,会触发read_before_write异常 //MAX_CHANNEL_QUEUE=0,并且先读后写,会触发read_before_write异常
std::cout << e.what() << std::endl; std::cout << e.what() << std::endl;

+ 1
- 1
tutorial/test_async_channel_mult_thread.cpp View File

} }
#endif #endif
} }
catch (channel_exception e)
catch (channel_exception& e)
{ {
//MAX_CHANNEL_QUEUE=0,并且先读后写,会触发read_before_write异常 //MAX_CHANNEL_QUEUE=0,并且先读后写,会触发read_before_write异常
scoped_lock<std::mutex> __lock(cout_mutex); scoped_lock<std::mutex> __lock(cout_mutex);

+ 1
- 1
tutorial/test_async_event.cpp View File

go[&]() -> future_t<> go[&]() -> future_t<>
{ {
for (int i = 0; i < _countof(evts); ++i)
for (size_t i = 0; i < _countof(evts); ++i)
{ {
intptr_t idx = co_await event_t::wait_any(evts); intptr_t idx = co_await event_t::wait_any(evts);
std::cout << "event " << idx << " signal!" << std::endl; std::cout << "event " << idx << " signal!" << std::endl;

+ 12
- 12
tutorial/test_async_modern_cb.cpp View File

//适配器类型 //适配器类型
using _Adapter_t = modern_callback_adapter_t<typename resumef::remove_cvref_t<_Callable_t>, void(std::string)>; using _Adapter_t = modern_callback_adapter_t<typename resumef::remove_cvref_t<_Callable_t>, void(std::string)>;
//通过适配器获得兼容_Signature_t类型的真正的回调,以及返回值_Return_t //通过适配器获得兼容_Signature_t类型的真正的回调,以及返回值_Return_t
auto adapter = typename _Adapter_t::traits(std::forward<_Callable_t>(token));
auto adapter = _Adapter_t::traits(std::forward<_Callable_t>(token));


//callback与token未必是同一个变量,甚至未必是同一个类型 //callback与token未必是同一个变量,甚至未必是同一个类型
std::thread([callback = std::move(std::get<0>(adapter)), value = std::forward<_Input_t>(value)] std::thread([callback = std::move(std::get<0>(adapter)), value = std::forward<_Input_t>(value)]
//或者宏版本写法 //或者宏版本写法
#define MODERN_CALLBACK_TRAITS(_Token_value, _Signature_t) \ #define MODERN_CALLBACK_TRAITS(_Token_value, _Signature_t) \
using _Adapter_t = modern_callback_adapter_t<typename resumef::remove_cvref_t<_Callable_t>, _Signature_t>; \ using _Adapter_t = modern_callback_adapter_t<typename resumef::remove_cvref_t<_Callable_t>, _Signature_t>; \
auto _Adapter_value = typename _Adapter_t::traits(std::forward<_Callable_t>(_Token_value))
auto _Adapter_value = _Adapter_t::traits(std::forward<_Callable_t>(_Token_value))
#define MODERN_CALLBACK_CALL() std::move(std::get<0>(_Adapter_value)) #define MODERN_CALLBACK_CALL() std::move(std::get<0>(_Adapter_value))
#define MODERN_CALLBACK_RETURN() return std::move(std::get<1>(_Adapter_value)).get() #define MODERN_CALLBACK_RETURN() return std::move(std::get<1>(_Adapter_value)).get()




auto get_future() const auto get_future() const
{ {
return _promise.get_future();
return this->_promise.get_future();
} }
}; };




void operator()() const void operator()() const
{ {
_promise.set_value();
this->_promise.set_value();
} }
}; };


void operator()(std::exception_ptr eptr) const void operator()(std::exception_ptr eptr) const
{ {
if (!eptr) if (!eptr)
_promise.set_value();
this->_promise.set_value();
else else
_promise.set_exception(std::move(eptr));
this->_promise.set_exception(std::move(eptr));
} }
}; };


template<typename Arg> template<typename Arg>
void operator()(Arg && arg) const void operator()(Arg && arg) const
{ {
_promise.set_value(std::forward<Arg>(arg));
this->_promise.set_value(std::forward<Arg>(arg));
} }
}; };


void operator()(std::exception_ptr eptr, Arg && arg) const void operator()(std::exception_ptr eptr, Arg && arg) const
{ {
if (!eptr) if (!eptr)
_promise.set_value(std::forward<Arg>(arg));
this->_promise.set_value(std::forward<Arg>(arg));
else else
_promise.set_exception(std::move(eptr));
this->_promise.set_exception(std::move(eptr));
} }
}; };


void operator()(Args&&... args) const void operator()(Args&&... args) const
{ {
static_assert(sizeof...(Args) == sizeof...(_Result_t), ""); static_assert(sizeof...(Args) == sizeof...(_Result_t), "");
_promise.set_value(std::make_tuple(std::forward<Args>(args)...));
this->_promise.set_value(std::make_tuple(std::forward<Args>(args)...));
} }
}; };


{ {
static_assert(sizeof...(Args) == sizeof...(_Result_t), ""); static_assert(sizeof...(Args) == sizeof...(_Result_t), "");
if (!eptr) if (!eptr)
_promise.set_value(std::make_tuple(std::forward<Args>(args)...));
this->_promise.set_value(std::make_tuple(std::forward<Args>(args)...));
else else
_promise.set_exception(std::move(eptr));
this->_promise.set_exception(std::move(eptr));
} }
}; };



+ 1
- 1
tutorial/test_async_suspend_always.cpp View File

using namespace resumef; using namespace resumef;
future_t<> test_loop_sleep(size_t _N, char * ch)
future_t<> test_loop_sleep(size_t _N, const char * ch)
{ {
using namespace std::chrono; using namespace std::chrono;

+ 2
- 2
tutorial/test_async_switch_scheduler.cpp View File

//循环直到sch_in_thread为nullptr //循环直到sch_in_thread为nullptr
for (;;) for (;;)
{ {
auto sch = sch_in_thread.load(std::memory_order::acquire);
auto sch = sch_in_thread.load(std::memory_order_acquire);
if (sch == nullptr) if (sch == nullptr)
break; break;
sch->run_one_batch(); sch->run_one_batch();
//这种情况下,没有生成 frame-context,因此,并没有promise_type被内嵌在frame-context里 //这种情况下,没有生成 frame-context,因此,并没有promise_type被内嵌在frame-context里
static future_t<int64_t> async_get_long(int64_t val) static future_t<int64_t> async_get_long(int64_t val)
{ {
resumef::awaitable_t<int64_t> awaitable;
awaitable_t<int64_t> awaitable;
callback_get_long(val, [awaitable](int64_t val) callback_get_long(val, [awaitable](int64_t val)
{ {
awaitable.set_value(val); awaitable.set_value(val);

+ 3
- 3
tutorial/test_async_when_all.cpp View File

co_await sleep_for(1ms * dt); co_await sleep_for(1ms * dt);
std::cout << dt << "@a" << std::endl; std::cout << dt << "@a" << std::endl;
return dt;
co_return dt;
}(), }(),
[]() ->future_t<> []() ->future_t<>
{ {
co_await sleep_for(1ms * dt); co_await sleep_for(1ms * dt);
std::cout << dt << "@" << name << std::endl; std::cout << dt << "@" << name << std::endl;
return dt;
co_return dt;
}; };
std::vector<future_t<int> > v{ my_sleep("g"), my_sleep("h"), my_sleep("i") }; std::vector<future_t<int> > v{ my_sleep("g"), my_sleep("h"), my_sleep("i") };
co_await sleep_for(1ms * dt); co_await sleep_for(1ms * dt);
std::cout << dt << "@" << name << std::endl; std::cout << dt << "@" << name << std::endl;
return dt;
co_return dt;
}; };
auto my_sleep_v = [](const char * name) -> future_t<> auto my_sleep_v = [](const char * name) -> future_t<>

+ 1
- 2
vs_proj/librf.cpp View File

#include <experimental/resumable> #include <experimental/resumable>
#include <experimental/generator> #include <experimental/generator>
#include <optional> #include <optional>
#include "async_wrapper.hpp"
extern void resumable_main_yield_return(); extern void resumable_main_yield_return();
extern void resumable_main_timer(); extern void resumable_main_timer();
{ {
(void)argc; (void)argc;
(void)argv; (void)argv;
resumable_main_switch_scheduler();
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]));

+ 1
- 1
vs_proj/librf.vcxproj View File

<ProjectGuid>{C1D4A6BD-592F-4E48-8178-7C87219BF80E}</ProjectGuid> <ProjectGuid>{C1D4A6BD-592F-4E48-8178-7C87219BF80E}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>librf</RootNamespace> <RootNamespace>librf</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<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">
<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>

Loading…
Cancel
Save