Sfoglia il codice sorgente

寻找调用的promise地址的规律

tags/v2.9.7
tearshark 6 anni fa
parent
commit
ef85658d00

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

@@ -44,6 +44,24 @@ namespace resumef
template<class... _Mutexes>
using scoped_lock = std::lock_guard<_Mutexes...>;
#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
{

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

@@ -5,9 +5,6 @@
namespace resumef
{
template <typename T = void>
struct promise_t;
template <typename T>
struct future_impl_t
{
@@ -34,7 +31,7 @@ namespace resumef
{
return _state->_ready;
}
void await_suspend(std::experimental::coroutine_handle<> resume_cb)
void await_suspend(coroutine_handle<> resume_cb)
{
_state->await_suspend(resume_cb);
}
@@ -147,6 +144,15 @@ namespace resumef
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>
struct promise_impl_t
{
@@ -159,9 +165,22 @@ namespace resumef
promise_impl_t()
: _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 & operator = (const promise_impl_t&) = delete;
@@ -196,37 +215,18 @@ namespace resumef
// 2、通过await启动另外一个子函数
// (1)情况下,无法区分是否已经拥有的resume_cb,可以特殊处理
// (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的对象,本协程已经准备好了删除了
std::experimental::suspend_never final_suspend() noexcept
auto final_suspend() noexcept
{
_state->final_suspend();
return{};
return std::experimental::suspend_never{};
}
//返回与之关联的future对象
@@ -326,7 +326,7 @@ namespace resumef
{
return _state->_ready;
}
void await_suspend(std::experimental::coroutine_handle<> resume_cb)
void await_suspend(coroutine_handle<> resume_cb)
{
_state->await_suspend(resume_cb);
}
@@ -341,5 +341,42 @@ namespace resumef
};
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 Vedi File

@@ -36,6 +36,7 @@ namespace resumef
}
virtual bool go_next(scheduler * schdler) override
{
_state->current_scheduler(schdler);
_state->resume();
return false;
}
@@ -61,7 +62,8 @@ namespace resumef
// Set all members first as calling coroutine may reset stuff here.
_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_)
@@ -73,6 +75,7 @@ namespace resumef
// Set all members first as calling coroutine may reset stuff here.
_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 Vedi File

@@ -112,6 +112,7 @@ namespace resumef
virtual bool go_next(scheduler * schdler) override
{
auto * _state = _future._state.get();
_state->current_scheduler(schdler);
_state->resume();
return !_state->ready() && !_state->_done;
}

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

@@ -9,6 +9,7 @@ std::atomic<intptr_t> g_resumef_evtctx_count = 0;
namespace resumef
{
static const char * future_error_string[(size_t)future_error::max__]
{
"none",

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

@@ -6,13 +6,19 @@
namespace resumef
{
template <typename T = void>
struct promise_t;
struct state_base
{
protected:
std::mutex _mtx; //for value, _exception
RF_API void set_value_none_lock();
private:
void * _this_promise = nullptr;
scheduler * _current_scheduler = nullptr;
public:
std::experimental::coroutine_handle<> _coro;
coroutine_handle<> _coro;
std::atomic<intptr_t> _count = 0; // tracks reference count of state object
std::exception_ptr _exception;
@@ -75,9 +81,13 @@ namespace resumef
{
if (_coro)
{
std::cout << "scheduler=" << current_scheduler()
<< ",coro=" << _coro.address()
<< ",this_promise=" << this_promise()
<< ",parent_promise=" << parent_promise() << std::endl;
auto coro = _coro;
_coro = nullptr;
//std::cout << "resume from " << coro.address() << " on thread " << std::this_thread::get_id() << std::endl;
coro();
}
}
@@ -94,6 +104,27 @@ namespace resumef
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交互的接口
@@ -101,7 +132,7 @@ namespace resumef
{
return _ready;
}
void await_suspend(std::experimental::coroutine_handle<> resume_cb)
void await_suspend(coroutine_handle<> resume_cb)
{
_coro = resume_cb;
}
@@ -162,6 +193,11 @@ namespace resumef
state_base::reset_none_lock();
_value = value_type{};
}
promise_t<_Ty> * parent_promise() const
{
return reinterpret_cast<promise_t<_Ty> *>(state_base::parent_promise());
}
};
template<>
@@ -192,6 +228,11 @@ namespace resumef
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

+ 10
- 3
tutorial/test_async_routine.cpp Vedi File

@@ -12,24 +12,31 @@ using namespace resumef;
future_vt test_routine_use_timer()
{
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);
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()
{
std::cout << "test_routine_use_timer_2" << std::endl;
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();
std::cout << "2:frame=" << _coro_frame_ptr() << ",promise=" << _coro_promise_ptr(void) << std::endl << std::endl;
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()
{
go test_routine_use_timer_2();
//test_routine_use_timer();
//go test_routine_use_timer();
g_scheduler.run_until_notask();
}

+ 1
- 1
vs_proj/librf.cpp Vedi File

@@ -19,7 +19,7 @@ extern void resumable_main_benchmark_mem();
int main(int argc, const char * argv[])
{
resumable_main_exception();
resumable_main_routine();
return 0;
resumable_main_yield_return();

Loading…
Annulla
Salva