Sfoglia il codice sorgente

整理多线程多调度器功能。

仍然没能正常调度
tags/v2.9.7
tearshark 6 anni fa
parent
commit
6c9f476658

+ 3
- 3
librf/src/future.h Vedi File

bool await_ready() bool await_ready()
{ {
return _state->_ready;
return _state->ready();
} }
void await_suspend(coroutine_handle<> resume_cb) void await_suspend(coroutine_handle<> resume_cb)
{ {
//if ready, can get value //if ready, can get value
bool ready() bool ready()
{ {
return _state->_ready;
return _state->ready();
} }
auto & get_value() auto & get_value()
{ {
bool await_ready() bool await_ready()
{ {
return _state->_ready;
return _state->ready();
} }
void await_suspend(coroutine_handle<> resume_cb) void await_suspend(coroutine_handle<> resume_cb)
{ {

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

{ {
auto * _state = _future._state.get(); auto * _state = _future._state.get();
_state->resume(); _state->resume();
return !_state->ready() && !_state->_done;
return !_state->ready() && !_state->done();
} }
virtual void cancel() override virtual void cancel() override
{ {

+ 2
- 6
librf/src/state.cpp Vedi File

{ {
#if RESUMEF_ENABLE_MULT_SCHEDULER #if RESUMEF_ENABLE_MULT_SCHEDULER
auto sch_ = this->current_scheduler(); auto sch_ = this->current_scheduler();
if (sch_ == nullptr)
sch_ = this_scheduler();
#else #else
auto sch_ = this_scheduler(); auto sch_ = this_scheduler();
#endif #endif
sch_->push_task_internal(new awaitable_task_t<state_base>(this));
if(sch_) sch_->push_task_internal(new awaitable_task_t<state_base>(this));
} }
} }
{ {
#if RESUMEF_ENABLE_MULT_SCHEDULER #if RESUMEF_ENABLE_MULT_SCHEDULER
auto sch_ = this->current_scheduler(); auto sch_ = this->current_scheduler();
if (sch_ == nullptr)
sch_ = this_scheduler();
#else #else
auto sch_ = this_scheduler(); auto sch_ = this_scheduler();
#endif #endif
sch_->push_task_internal(new awaitable_task_t<state_base>(this));
if (sch_) sch_->push_task_internal(new awaitable_task_t<state_base>(this));
} }
} }

+ 19
- 6
librf/src/state.h Vedi File

RF_API void set_value_none_lock(); RF_API void set_value_none_lock();
#if RESUMEF_ENABLE_MULT_SCHEDULER #if RESUMEF_ENABLE_MULT_SCHEDULER
private: private:
void * _this_promise = nullptr;
std::atomic<void *> _this_promise = nullptr;
scheduler * _current_scheduler = nullptr; scheduler * _current_scheduler = nullptr;
std::vector<counted_ptr<state_base>> _depend_states; std::vector<counted_ptr<state_base>> _depend_states;
#endif #endif
public:
protected:
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;
bool _ready = false;
bool _cancellation = false;
bool _done = false;
std::atomic<bool> _ready = false;
std::atomic<bool> _cancellation = false;
std::atomic<bool> _done = false;
public:
state_base() state_base()
{ {
#if RESUMEF_DEBUG_COUNTER #if RESUMEF_DEBUG_COUNTER
{ {
return _ready; return _ready;
} }
bool done() const
{
return _done;
}
void reset_none_lock() void reset_none_lock()
{ {
scoped_lock<lock_type> __guard(_mtx);
_coro = nullptr; _coro = nullptr;
_ready = false; _ready = false;
} }
} }
void resume() void resume()
{ {
scoped_lock<lock_type> __guard(_mtx);
if (_coro) if (_coro)
{ {
#if RESUMEF_DEBUG_COUNTER #if RESUMEF_DEBUG_COUNTER
#endif #endif
auto coro = _coro; auto coro = _coro;
_coro = nullptr; _coro = nullptr;
coro(); coro();
} }
} }
#if RESUMEF_ENABLE_MULT_SCHEDULER #if RESUMEF_ENABLE_MULT_SCHEDULER
promise_t<void> * parent_promise() const; promise_t<void> * parent_promise() const;
//scheduler * parent_scheduler() const;
scheduler * parent_scheduler() const;
void * this_promise() const void * this_promise() const
{ {
void await_suspend(coroutine_handle<> resume_cb); void await_suspend(coroutine_handle<> resume_cb);
void final_suspend() void final_suspend()
{ {
scoped_lock<lock_type> __guard(_mtx);
_done = true; _done = true;
} }
//以上是通过future_t/promise_t, 与编译器生成的resumable function交互的接口 //以上是通过future_t/promise_t, 与编译器生成的resumable function交互的接口
_value = value_type{}; _value = value_type{};
} }
#if RESUMEF_ENABLE_MULT_SCHEDULER
promise_t<_Ty> * parent_promise() const promise_t<_Ty> * parent_promise() const
{ {
return reinterpret_cast<promise_t<_Ty> *>(state_base::parent_promise()); return reinterpret_cast<promise_t<_Ty> *>(state_base::parent_promise());
} }
#endif
}; };
template<> template<>

+ 14
- 6
tutorial/test_async_channel_mult_thread.cpp Vedi File

using namespace std::chrono; using namespace std::chrono;
static std::mutex cout_mutex; static std::mutex cout_mutex;
std::atomic<intptr_t> gcounter = 0;
#define OUTPUT_DEBUG 0 #define OUTPUT_DEBUG 0
try try
{ {
auto val = co_await c.read(); auto val = co_await c.read();
++gcounter;
#if OUTPUT_DEBUG #if OUTPUT_DEBUG
{ {
scoped_lock<std::mutex> __lock(cout_mutex); scoped_lock<std::mutex> __lock(cout_mutex);
std::thread write_th([&] std::thread write_th([&]
{ {
//local_scheduler my_scheduler; //2017/11/27日,仍然存在BUG。真多线程下调度,存在有协程无法被调度完成的BUG
local_scheduler my_scheduler; //2017/12/14日,仍然存在BUG。真多线程下调度,存在有协程无法被调度完成的BUG
go test_channel_producer(c, BATCH * N); go test_channel_producer(c, BATCH * N);
#if RESUMEF_ENABLE_MULT_SCHEDULER
this_scheduler()->run_until_notask(); this_scheduler()->run_until_notask();
#endif
std::cout << "Write OK\r\n"; std::cout << "Write OK\r\n";
}); });
{ {
read_th[i] = std::thread([&] read_th[i] = std::thread([&]
{ {
//local_scheduler my_scheduler; //2017/11/27日,仍然存在BUG。真多线程下调度,存在有协程无法被调度完成的BUG
local_scheduler my_scheduler; //2017/12/14日,仍然存在BUG。真多线程下调度,存在有协程无法被调度完成的BUG
go test_channel_consumer(c, BATCH); go test_channel_consumer(c, BATCH);
#if RESUMEF_ENABLE_MULT_SCHEDULER
this_scheduler()->run_until_notask(); this_scheduler()->run_until_notask();
#endif
std::cout << "Read OK\r\n"; std::cout << "Read OK\r\n";
}); });
} }
#if !RESUMEF_ENABLE_MULT_SCHEDULER
std::this_thread::sleep_for(100ms);
scheduler::g_scheduler.run_until_notask();
#endif
for(auto & th : read_th) for(auto & th : read_th)
th.join(); th.join();
write_th.join(); write_th.join();
std::cout << "OK" << std::endl;
std::cout << "OK: counter = " << gcounter.load() << std::endl;
_getch(); _getch();
} }

+ 1
- 1
vs_proj/librf.vcxproj Vedi File

<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;RESUMEF_DEBUG_COUNTER=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;RESUMEF_DEBUG_COUNTER=0;RESUMEF_ENABLE_MULT_SCHEDULER=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\librf;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\librf;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/await /std:c++latest </AdditionalOptions> <AdditionalOptions>/await /std:c++latest </AdditionalOptions>

Loading…
Annulla
Salva