Browse Source

generator_t的state也跟promise分配在一起。

tags/v2.9.7
tearshark 4 years ago
parent
commit
d1de24135f

+ 37
- 6
librf/src/generator.h View File

@@ -32,9 +32,10 @@ namespace resumef
generator_iterator& operator++()
{
_Coro.resume();
if (_Coro.done())
_Coro = nullptr;
else
_Coro.resume();
return *this;
}
@@ -106,6 +107,17 @@ namespace resumef
_Ty const* _CurrentValue;
promise_type()
{
state_type* st = get_state();
new(st) state_type(coroutine_handle<promise_type>::from_promise(*this));
st->lock();
}
promise_type(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& get_return_object()
{
return *this;
@@ -145,6 +157,13 @@ namespace resumef
return std::forward<_Uty>(_Whatever);
}
state_type* get_state()
{
size_t _State_size = _Align_size<state_type>();
char* ptr = reinterpret_cast<char*>(this) - _State_size;
return reinterpret_cast<state_type*>(ptr);
}
using _Alloc_char = typename std::allocator_traits<_Alloc>::template rebind_alloc<char>;
static_assert(std::is_same_v<char*, typename std::allocator_traits<_Alloc_char>::pointer>,
"generator_t does not support allocators with fancy pointer types");
@@ -153,15 +172,27 @@ namespace resumef
void* operator new(size_t _Size)
{
size_t _State_size = _Align_size<state_type>();
assert(_Size >= sizeof(uint32_t) && _Size < std::numeric_limits<uint32_t>::max() - sizeof(_State_size));
#if RESUMEF_DEBUG_COUNTER
std::cout << "generator_promise::new, size=" << (_Size + _State_size) << std::endl;
#endif
_Alloc_char _Al;
void* ptr = _Al.allocate(_Size);
return ptr;
char* ptr = _Al.allocate(_Size + _State_size);
return ptr + _State_size;
}
void operator delete(void* _Ptr, size_t _Size)
{
size_t _State_size = _Align_size<state_type>();
assert(_Size >= sizeof(uint32_t) && _Size < std::numeric_limits<uint32_t>::max() - sizeof(_State_size));
*reinterpret_cast<uint32_t*>(_Ptr) = static_cast<uint32_t>(_Size + _State_size);
_Alloc_char _Al;
return _Al.deallocate(static_cast<char*>(_Ptr), _Size);
state_type* st = reinterpret_cast<state_type*>(static_cast<char*>(_Ptr) - _State_size);
st->unlock();
}
};
@@ -216,11 +247,11 @@ namespace resumef
}
}
coroutine_handle<promise_type> detach()
state_type* detach_state()
{
auto t = _Coro;
_Coro = nullptr;
return t;
return t.promise().get_state();
}
private:

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

@@ -48,7 +48,7 @@ namespace resumef
size_t _State_size = _Align_size<state_type>();
assert(_Size >= sizeof(uint32_t) && _Size < std::numeric_limits<uint32_t>::max() - sizeof(_State_size));
#if RESUMEF_DEBUG_COUNTER
std::cout << "promise::new, size=" << (_Size + _State_size) << std::endl;
std::cout << "future_promise::new, size=" << (_Size + _State_size) << std::endl;
#endif

_Alloc_char _Al;

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

@@ -60,7 +60,7 @@ namespace resumef
protected:
void initialize(future_type&& f)
{
_state = new state_type(f.detach());
_state = f.detach_state();
}
};

+ 14
- 2
librf/src/state.cpp View File

@@ -11,7 +11,7 @@ namespace resumef
void state_future_t::destroy_deallocate()
{
size_t _Size = this->_Alloc_size;
size_t _Size = this->_alloc_size;
#if RESUMEF_DEBUG_COUNTER
std::cout << "destroy_deallocate, size=" << _Size << std::endl;
#endif
@@ -23,7 +23,16 @@ namespace resumef
void state_generator_t::destroy_deallocate()
{
delete this;
size_t _Size = _Align_size<state_generator_t>();
char* _Ptr = reinterpret_cast<char*>(this) + _Size;
_Size = *reinterpret_cast<uint32_t*>(_Ptr);
#if RESUMEF_DEBUG_COUNTER
std::cout << "destroy_deallocate, size=" << _Size << std::endl;
#endif
this->~state_generator_t();
_Alloc_char _Al;
return _Al.deallocate(reinterpret_cast<char*>(this), _Size);
}
void state_generator_t::resume()
@@ -33,8 +42,11 @@ namespace resumef
_coro.resume();
if (_coro.done())
{
coroutine_handle<> handler = _coro;
_coro = nullptr;
_scheduler->del_final(this);
handler.destroy();
}
else
{

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

@@ -11,8 +11,6 @@ namespace resumef
struct state_base_t
{
using _Alloc_char = std::allocator<char>;
RF_API virtual ~state_base_t();
private:
std::atomic<intptr_t> _count{0};
public:
@@ -34,6 +32,8 @@ namespace resumef
// 一、经过co_await操作后,_coro在初始时不会为nullptr。
// 二、没有co_await操作,直接加入到了调度器里,则_coro在初始时为nullptr。调度器需要特殊处理此种情况。
coroutine_handle<> _coro;
virtual ~state_base_t();
private:
virtual void destroy_deallocate() = 0;
public:
@@ -53,16 +53,24 @@ namespace resumef
struct state_generator_t : public state_base_t
{
public:
state_generator_t(coroutine_handle<> handler)
{
_coro = handler;
}
private:
virtual void destroy_deallocate() override;
public:
virtual void resume() override;
virtual bool has_handler() const override;
virtual bool is_ready() const override;
static state_generator_t * _Alloc_state(coroutine_handle<> handler)
{
#if RESUMEF_DEBUG_COUNTER
std::cout << "state_generator_t::alloc, size=" << sizeof(state_generator_t) << std::endl;
#endif
return new state_generator_t(handler);
}
};
struct state_future_t : public state_base_t
@@ -76,7 +84,7 @@ namespace resumef
intptr_t _id;
#endif
std::exception_ptr _exception;
uint32_t _Alloc_size;
uint32_t _alloc_size;
bool _has_value = false;
bool _is_awaitor;
bool _is_initor = false;
@@ -112,7 +120,7 @@ namespace resumef
}
void set_alloc_size(uint32_t val)
{
_Alloc_size = val;
_alloc_size = val;
}
void set_exception(std::exception_ptr e);
@@ -146,11 +154,11 @@ namespace resumef
state_t() :state_future_t()
{
_Alloc_size = sizeof(*this);
_alloc_size = sizeof(*this);
}
explicit state_t(bool awaitor) :state_future_t(awaitor)
{
_Alloc_size = sizeof(*this);
_alloc_size = sizeof(*this);
}
private:
union union_value_type
@@ -162,12 +170,13 @@ namespace resumef
~union_value_type() {}
};
union_value_type uv;
public:
~state_t()
{
if (_has_value)
uv._value.~value_type();
}
public:
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);
@@ -182,11 +191,11 @@ namespace resumef
state_t() :state_future_t()
{
_Alloc_size = sizeof(*this);
_alloc_size = sizeof(*this);
}
explicit state_t(bool awaitor) :state_future_t(awaitor)
{
_Alloc_size = sizeof(*this);
_alloc_size = sizeof(*this);
}
public:
void future_await_resume();

+ 5
- 0
tutorial/test_async_yield_return.cpp View File

@@ -59,6 +59,11 @@ auto test_yield_void() -> generator_t<>
void resumable_main_yield_return()
{
for (int i : test_yield_int())
{
std::cout << i << " had return" << std::endl;
}
go test_yield_int();
this_scheduler()->run_until_notask();

+ 1
- 1
vs_proj/librf.cpp View File

@@ -31,7 +31,7 @@ int main(int argc, const char* argv[])
{
(void)argc;
(void)argv;
resumable_main_routine();
resumable_main_yield_return();
//if (argc > 1)
// resumable_main_benchmark_asio_client(atoi(argv[1]));

Loading…
Cancel
Save