Browse Source

寻找调用的promise地址的规律

tags/v2.9.7
tearshark 6 years ago
parent
commit
ef85658d00

+ 18
- 0
librf/src/def.h View File

template<class... _Mutexes> template<class... _Mutexes>
using scoped_lock = std::lock_guard<_Mutexes...>; using scoped_lock = std::lock_guard<_Mutexes...>;
#endif #endif
template<typename _PromiseT = void>
using coroutine_handle = std::experimental::coroutine_handle<_PromiseT>;
template<typename _PromiseT = void>
inline void * _coro_function_ptr(coroutine_handle<> coro)
{
auto frame_prefix = (coroutine_handle<void>::_Resumable_frame_prefix*)coro.address();
return reinterpret_cast<void *>(frame_prefix->_Fn);
}
template<typename _PromiseT>
inline _PromiseT * _coro_promise_ptr__(void * _Ptr)
{
using coroutine_instance = coroutine_handle<_PromiseT>;
return reinterpret_cast<_PromiseT *>(reinterpret_cast<char *>(_Ptr) - coroutine_instance::_ALIGNED_SIZE);
}
#define _coro_promise_ptr(T) _coro_promise_ptr__<resumef::promise_t<T> >(_coro_frame_ptr())
enum struct future_error enum struct future_error
{ {

+ 68
- 31
librf/src/future.h View File

namespace resumef namespace resumef
{ {
template <typename T = void>
struct promise_t;
template <typename T> template <typename T>
struct future_impl_t struct future_impl_t
{ {
{ {
return _state->_ready; return _state->_ready;
} }
void await_suspend(std::experimental::coroutine_handle<> resume_cb)
void await_suspend(coroutine_handle<> resume_cb)
{ {
_state->await_suspend(resume_cb); _state->await_suspend(resume_cb);
} }
using future_vt = future_t<void>; using future_vt = future_t<void>;
template<class state_type>
struct awaitor_initial_suspend
{
counted_ptr<state_type> _state;
bool await_ready() noexcept;
void await_suspend(coroutine_handle<> resume_cb) noexcept;
void await_resume() noexcept;
};
template <typename T> template <typename T>
struct promise_impl_t struct promise_impl_t
{ {
promise_impl_t() promise_impl_t()
: _state(make_counted<state_type>()) : _state(make_counted<state_type>())
{ {
_state->this_promise(this);
}
promise_impl_t(promise_impl_t&& _Right)
: _state(std::move(_Right._state))
{
_state->this_promise(this);
}
promise_impl_t & operator = (promise_impl_t&& _Right)
{
if (this != _Right)
{
_state = std::move(_Right._state);
_state->this_promise(this);
}
return *this;
} }
promise_impl_t(promise_impl_t&&) = default;
promise_impl_t & operator = (promise_impl_t&&) = default;
promise_impl_t(const promise_impl_t&) = delete; promise_impl_t(const promise_impl_t&) = delete;
promise_impl_t & operator = (const promise_impl_t&) = delete; promise_impl_t & operator = (const promise_impl_t&) = delete;
// 2、通过await启动另外一个子函数 // 2、通过await启动另外一个子函数
// (1)情况下,无法区分是否已经拥有的resume_cb,可以特殊处理 // (1)情况下,无法区分是否已经拥有的resume_cb,可以特殊处理
// (2)情况下,返回准备好了,让编译器继续运行 // (2)情况下,返回准备好了,让编译器继续运行
std::experimental::suspend_never initial_suspend() noexcept
auto initial_suspend() noexcept
{ {
return {};
/*
struct AWaitor
{
counted_ptr<state_tt> _state;
bool await_ready() _NOEXCEPT
{
return false;
}
void await_suspend(std::experimental::coroutine_handle<> resume_cb) _NOEXCEPT
{
_state->await_suspend(resume_cb);
_state->run_in_coroutine(this_coroutine());
}
void await_resume() _NOEXCEPT
{
}
};
return AWaitor{ _state };
*/
return std::experimental::suspend_never{};
//return awaitor_initial_suspend<state_type>{ _state };
} }
//这在一个协程被销毁之时调用。 //这在一个协程被销毁之时调用。
//我们选择不挂起协程,只是通知state的对象,本协程已经准备好了删除了 //我们选择不挂起协程,只是通知state的对象,本协程已经准备好了删除了
std::experimental::suspend_never final_suspend() noexcept
auto final_suspend() noexcept
{ {
_state->final_suspend(); _state->final_suspend();
return{};
return std::experimental::suspend_never{};
} }
//返回与之关联的future对象 //返回与之关联的future对象
{ {
return _state->_ready; return _state->_ready;
} }
void await_suspend(std::experimental::coroutine_handle<> resume_cb)
void await_suspend(coroutine_handle<> resume_cb)
{ {
_state->await_suspend(resume_cb); _state->await_suspend(resume_cb);
} }
}; };
using awaitable_vt = awaitable_t<void>; using awaitable_vt = awaitable_t<void>;
inline promise_t<void> * state_base::parent_promise() const
{
if (_coro) return _coro_promise_ptr__<promise_t<void>>(_coro.address());
return nullptr;
}
inline scheduler * state_base::parent_scheduler() const
{
auto promise_ = parent_promise();
if (promise_)
return promise_->_state->current_scheduler();
return nullptr;
}
template<class state_type>
bool awaitor_initial_suspend<state_type>::await_ready() noexcept
{
return false;
}
template<class state_type>
void awaitor_initial_suspend<state_type>::await_suspend(coroutine_handle<> resume_cb) noexcept
{
_state->await_suspend(resume_cb);
scheduler * sch_ = _state->parent_scheduler();
if (sch_ != nullptr)
{
_state->current_scheduler(sch_);
_state->resume();
}
}
template<class state_type>
void awaitor_initial_suspend<state_type>::await_resume() noexcept
{
}
} }

+ 5
- 2
librf/src/rf_task.cpp View File

} }
virtual bool go_next(scheduler * schdler) override virtual bool go_next(scheduler * schdler) override
{ {
_state->current_scheduler(schdler);
_state->resume(); _state->resume();
return false; return false;
} }
// Set all members first as calling coroutine may reset stuff here. // Set all members first as calling coroutine may reset stuff here.
_ready = true; _ready = true;


this_scheduler()->push_task_internal(new awaitable_task_t<state_base>(this));
auto sch_ = this->parent_scheduler();
sch_->push_task_internal(new awaitable_task_t<state_base>(this));
} }
void state_base::set_exception(std::exception_ptr && e_) void state_base::set_exception(std::exception_ptr && e_)
// Set all members first as calling coroutine may reset stuff here. // Set all members first as calling coroutine may reset stuff here.
_ready = true; _ready = true;


this_scheduler()->push_task_internal(new awaitable_task_t<state_base>(this));
auto sch_ = this->parent_scheduler();
sch_->push_task_internal(new awaitable_task_t<state_base>(this));
} }
} }

+ 1
- 0
librf/src/rf_task.h View File

virtual bool go_next(scheduler * schdler) override virtual bool go_next(scheduler * schdler) override
{ {
auto * _state = _future._state.get(); auto * _state = _future._state.get();
_state->current_scheduler(schdler);
_state->resume(); _state->resume();
return !_state->ready() && !_state->_done; return !_state->ready() && !_state->_done;
} }

+ 1
- 0
librf/src/scheduler.cpp View File

namespace resumef namespace resumef
{ {
static const char * future_error_string[(size_t)future_error::max__] static const char * future_error_string[(size_t)future_error::max__]
{ {
"none", "none",

+ 44
- 3
librf/src/state.h View File

namespace resumef namespace resumef
{ {
template <typename T = void>
struct promise_t;
struct state_base struct state_base
{ {
protected: protected:
std::mutex _mtx; //for value, _exception std::mutex _mtx; //for value, _exception
RF_API void set_value_none_lock(); RF_API void set_value_none_lock();
private:
void * _this_promise = nullptr;
scheduler * _current_scheduler = nullptr;
public: public:
std::experimental::coroutine_handle<> _coro;
coroutine_handle<> _coro;
std::atomic<intptr_t> _count = 0; // tracks reference count of state object std::atomic<intptr_t> _count = 0; // tracks reference count of state object
std::exception_ptr _exception; std::exception_ptr _exception;
{ {
if (_coro) if (_coro)
{ {
std::cout << "scheduler=" << current_scheduler()
<< ",coro=" << _coro.address()
<< ",this_promise=" << this_promise()
<< ",parent_promise=" << parent_promise() << std::endl;
auto coro = _coro; auto coro = _coro;
_coro = nullptr; _coro = nullptr;
//std::cout << "resume from " << coro.address() << " on thread " << std::this_thread::get_id() << std::endl;
coro(); coro();
} }
} }
delete this; delete this;
} }
promise_t<void> * parent_promise() const;
scheduler * parent_scheduler() const;
void * this_promise() const
{
return _this_promise;
}
void this_promise(void * promise_)
{
_this_promise = promise_;
}
scheduler * current_scheduler() const
{
return _current_scheduler;
}
void current_scheduler(scheduler * sch_)
{
_current_scheduler = sch_;
}
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
//以下是通过future_t/promise_t, 与编译器生成的resumable function交互的接口 //以下是通过future_t/promise_t, 与编译器生成的resumable function交互的接口
{ {
return _ready; return _ready;
} }
void await_suspend(std::experimental::coroutine_handle<> resume_cb)
void await_suspend(coroutine_handle<> resume_cb)
{ {
_coro = resume_cb; _coro = resume_cb;
} }
state_base::reset_none_lock(); state_base::reset_none_lock();
_value = value_type{}; _value = value_type{};
} }
promise_t<_Ty> * parent_promise() const
{
return reinterpret_cast<promise_t<_Ty> *>(state_base::parent_promise());
}
}; };
template<> template<>
reset_none_lock(); reset_none_lock();
} }
promise_t<void> * parent_promise() const
{
return reinterpret_cast<promise_t<void> *>(state_base::parent_promise());
}
}; };
// counted_ptr is similar to shared_ptr but allows explicit control // counted_ptr is similar to shared_ptr but allows explicit control

+ 10
- 3
tutorial/test_async_routine.cpp View File

future_vt test_routine_use_timer() future_vt test_routine_use_timer()
{ {
using namespace std::chrono; using namespace std::chrono;
std::cout << "test_routine_use_timer" << std::endl;
for (size_t i = 0; i < 10; ++i)
for (size_t i = 0; i < 3; ++i)
{ {
co_await resumef::sleep_for(100ms); co_await resumef::sleep_for(100ms);
std::cout << "timer after 100ms." << std::endl;
std::cout << "timer after 100ms" << std::endl;
std::cout << "1:frame=" << _coro_frame_ptr() << ",promise=" << _coro_promise_ptr(void) << std::endl << std::endl;
} }
} }
future_vt test_routine_use_timer_2() future_vt test_routine_use_timer_2()
{ {
std::cout << "test_routine_use_timer_2" << std::endl;
co_await test_routine_use_timer(); co_await test_routine_use_timer();
std::cout << "2:frame=" << _coro_frame_ptr() << ",promise=" << _coro_promise_ptr(void) << std::endl << std::endl;
co_await test_routine_use_timer(); co_await test_routine_use_timer();
std::cout << "2:frame=" << _coro_frame_ptr() << ",promise=" << _coro_promise_ptr(void) << std::endl << std::endl;
co_await test_routine_use_timer(); co_await test_routine_use_timer();
std::cout << "2:frame=" << _coro_frame_ptr() << ",promise=" << _coro_promise_ptr(void) << std::endl << std::endl;
} }
void resumable_main_routine() void resumable_main_routine()
{ {
go test_routine_use_timer_2(); go test_routine_use_timer_2();
//test_routine_use_timer();
//go test_routine_use_timer();
g_scheduler.run_until_notask(); g_scheduler.run_until_notask();
} }

+ 1
- 1
vs_proj/librf.cpp View File

int main(int argc, const char * argv[]) int main(int argc, const char * argv[])
{ {
resumable_main_exception();
resumable_main_routine();
return 0; return 0;
resumable_main_yield_return(); resumable_main_yield_return();

Loading…
Cancel
Save