1
0
şunun yansıması https://github.com/tearshark/librf.git eşitlendi 2024-10-04 08:50:31 +08:00
librf/source/scheduler.cpp

204 satır
4.4 KiB
C++
Ham Suçlama Geçmiş

Bu dosya muğlak Evrensel Kodlu karakter içeriyor

Bu dosya, başka karakterlerle karıştırılabilecek evrensel kodlu karakter içeriyor. Eğer bunu kasıtlı olarak yaptıysanız bu uyarıyı yok sayabilirsiniz. Gizli karakterleri göstermek için Kaçış Karakterli düğmesine tıklayın.

#include "librf/librf.h"
#if RESUMEF_DEBUG_COUNTER
std::mutex g_resumef_cout_mutex;
std::atomic<intptr_t> g_resumef_state_count = 0;
std::atomic<intptr_t> g_resumef_task_count = 0;
std::atomic<intptr_t> g_resumef_evtctx_count = 0;
std::atomic<intptr_t> g_resumef_state_id = 0;
#endif
namespace librf
{
const char * future_error_string[(size_t)error_code::max__]
{
"none",
"not_ready",
"already_acquired",
"unlock_more",
"read_before_write",
"timer_canceled",
"not_await_lock",
"stop_requested",
};
char sz_future_error_buffer[256];
LIBRF_API const char * get_error_string(error_code fe, const char * classname)
{
if (classname)
{
#if defined(__clang__) || defined(__GNUC__)
#define sprintf_s sprintf
#endif
sprintf_s(sz_future_error_buffer, "%s, code=%s", classname, future_error_string[(size_t)(fe)]);
return sz_future_error_buffer;
}
return future_error_string[(size_t)(fe)];
}
thread_local scheduler_t * th_scheduler_ptr = nullptr;
//获得当前线程下的调度器
LIBRF_API scheduler_t * this_scheduler()
{
return th_scheduler_ptr ? th_scheduler_ptr : &scheduler_t::g_scheduler;
}
LIBRF_API local_scheduler_t::local_scheduler_t()
{
if (th_scheduler_ptr == nullptr)
{
_scheduler_ptr = new scheduler_t;
th_scheduler_ptr = _scheduler_ptr;
}
else
{
_scheduler_ptr = nullptr;
}
}
LIBRF_API local_scheduler_t::local_scheduler_t(scheduler_t& sch) noexcept
{
if (th_scheduler_ptr == nullptr)
{
th_scheduler_ptr = &sch;
}
_scheduler_ptr = nullptr;
}
LIBRF_API local_scheduler_t::~local_scheduler_t()
{
if (th_scheduler_ptr == _scheduler_ptr)
th_scheduler_ptr = nullptr;
delete _scheduler_ptr;
}
LIBRF_API scheduler_t::scheduler_t()
: _timer(std::make_shared<timer_manager>())
{
_runing_states.reserve(1024);
_cached_states.reserve(1024);
if (th_scheduler_ptr == nullptr)
th_scheduler_ptr = this;
}
LIBRF_API scheduler_t::~scheduler_t()
{
//cancel_all_task_();
if (th_scheduler_ptr == this)
th_scheduler_ptr = nullptr;
}
LIBRF_API task_t* scheduler_t::new_task(task_t * task)
{
state_base_t* sptr = task->_state.get();
sptr->set_scheduler(this);
{
#if !RESUMEF_DISABLE_MULT_THREAD
scoped_lock<spinlock> __guard(_lock_ready);
#endif
_ready_task.emplace(sptr, task);
}
//如果是单独的future没有被co_await过则handler是nullptr。
if (sptr->has_handler())
{
add_generator(sptr);
}
return task;
}
LIBRF_API std::unique_ptr<task_t> scheduler_t::del_switch(state_base_t* sptr)
{
#if !RESUMEF_DISABLE_MULT_THREAD
scoped_lock<spinlock> __guard(_lock_ready);
#endif
std::unique_ptr<task_t> task_ptr;
auto iter = this->_ready_task.find(sptr);
if (iter != this->_ready_task.end())
{
task_ptr = std::exchange(iter->second, nullptr);
this->_ready_task.erase(iter);
}
return task_ptr;
}
LIBRF_API void scheduler_t::request_stop_all_if_possible()
{
scoped_lock<spinlock> __guard(_lock_ready);
for (auto& kv : this->_ready_task)
kv.second->request_stop_if_possible();
//this->_ready_task.clear();
this->_timer->clear();
}
/*
void scheduler_t::cancel_all_task_()
{
scoped_lock<spinlock, spinlock> __guard(_lock_ready, _lock_running);
this->_ready_task.clear();
this->_runing_states.clear();
}
void scheduler_t::break_all()
{
cancel_all_task_();
this->_timer->clear();
}
*/
LIBRF_API bool scheduler_t::run_one_batch()
{
this->_timer->update();
{
#if !RESUMEF_DISABLE_MULT_THREAD
scoped_lock<spinlock> __guard(_lock_running);
#endif
if (likely(_runing_states.empty()))
return false;
std::swap(_cached_states, _runing_states);
}
for (state_sptr& sptr : _cached_states)
sptr->resume();
_cached_states.clear();
return true;
}
LIBRF_API void scheduler_t::run_until_notask()
{
for(;;)
{
//介于网上有人做评测,导致单协程切换数据很难看,那就注释掉吧。
//std::this_thread::yield();
if (likely(this->run_one_batch())) continue; //当前运行了一个state则认为还可能有任务未完成
{
#if !RESUMEF_DISABLE_MULT_THREAD
scoped_lock<spinlock> __guard(_lock_ready);
#endif
if (likely(!_ready_task.empty())) continue; //当前还存在task则必然还有任务未完成
}
if (unlikely(!_timer->empty())) continue; //定时器不为空,也需要等待定时器触发
break;
};
}
LIBRF_API scheduler_t scheduler_t::g_scheduler;
}