Browse Source

兼容clang

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

+ 14
- 24
librf/src/event_v2.inl View File

@@ -33,7 +33,7 @@ RESUMEF_NS
bool try_wait_one() noexcept
{
if (_counter.load(std::memory_order_acquire) > 0)
if (_counter.load(std::memory_order_consume) > 0)
{
if (_counter.fetch_add(-1, std::memory_order_acq_rel) > 0)
return true;
@@ -156,6 +156,7 @@ RESUMEF_NS
bool await_ready() noexcept
{
scoped_lock<detail::event_v2_impl::lock_type> lock_(_event->_lock);
return _event->try_wait_one();
}
@@ -215,10 +216,10 @@ RESUMEF_NS
auto* parent_state = promise.get_state();
scheduler_t* sch = parent_state->get_scheduler();
_state->_thandler = sch->timer()->add_handler(_tp, [_state = _state](bool canceld)
this->_state->_thandler = sch->timer()->add_handler(_tp, [st = this->_state](bool canceld)
{
if (!canceld)
_state->on_timeout();
st->on_timeout();
});
return true;
@@ -259,35 +260,23 @@ RESUMEF_NS
bool await_ready() noexcept
{
if (_begin == _end)
return true;
for (auto iter = _begin; iter != _end; ++iter)
{
detail::event_v2_impl* evt = (*iter)._event.get();
if (evt->try_wait_one())
{
_event = evt;
return true;
}
}
return false;
return _begin == _end;
}
template<class _PromiseT, typename = std::enable_if_t<traits::is_promise_v<_PromiseT>>>
bool await_suspend(coroutine_handle<_PromiseT> handler)
{
std::vector<detail::event_v2_impl::lock_type> lockes;
using ref_lock_type = std::reference_wrapper<detail::event_v2_impl::lock_type>;
std::vector<ref_lock_type> lockes;
lockes.reserve(std::distance(_begin, _end));
for (auto iter = _begin; iter != _end; ++iter)
{
detail::event_v2_impl* evt = (*iter)._event.get();
lockes.push_back(evt->_lock);
lockes.emplace_back(std::ref(evt->_lock));
}
scoped_lock_range<detail::event_v2_impl::lock_type> lock_(lockes);
scoped_lock_range<ref_lock_type> lock_(lockes);
for (auto iter = _begin; iter != _end; ++iter)
{
@@ -355,7 +344,7 @@ RESUMEF_NS
struct [[nodiscard]] event_t::timeout_any_awaiter : timeout_awaitor_impl<event_t::any_awaiter<_Iter>>
{
timeout_any_awaiter(clock_type::time_point tp, _Iter begin, _Iter end) noexcept
: timeout_awaitor_impl(tp, begin, end)
: timeout_awaitor_impl<event_t::any_awaiter<_Iter>>(tp, begin, end)
{}
};
@@ -399,7 +388,8 @@ RESUMEF_NS
{
intptr_t count = std::distance(_begin, _end);
std::vector<detail::event_v2_impl::lock_type> lockes;
using ref_lock_type = std::reference_wrapper<detail::event_v2_impl::lock_type>;
std::vector<ref_lock_type> lockes;
lockes.reserve(count);
for (auto iter = _begin; iter != _end; ++iter)
@@ -411,7 +401,7 @@ RESUMEF_NS
_state = new detail::state_event_all_t(count, _value);
(void)_state->on_await_suspend(handler);
scoped_lock_range<detail::event_v2_impl::lock_type> lock_(lockes);
scoped_lock_range<ref_lock_type> lock_(lockes);
for (auto iter = _begin; iter != _end; ++iter)
{
@@ -468,7 +458,7 @@ RESUMEF_NS
struct [[nodiscard]] event_t::timeout_all_awaiter : timeout_awaitor_impl<event_t::all_awaiter<_Iter>>
{
timeout_all_awaiter(clock_type::time_point tp, _Iter begin, _Iter end) noexcept
: timeout_awaitor_impl(tp, begin, end)
: timeout_awaitor_impl<event_t::all_awaiter<_Iter>>(tp, begin, end)
{}
};

+ 41
- 10
librf/src/spinlock.h View File

@@ -91,21 +91,52 @@ RESUMEF_NS
namespace detail
{
template<class _Ty>
void _Lock_ref(_Ty& _LkN)
{
_LkN.lock();
}
template<class _Ty>
void _Lock_ref(std::reference_wrapper<_Ty> _LkN)
{
_LkN.get().lock();
}
template<class _Ty>
void _Unlock_ref(_Ty& _LkN)
{
_LkN.unlock();
}
template<class _Ty>
void _Unlock_ref(std::reference_wrapper<_Ty> _LkN)
{
_LkN.get().unlock();
}
template<class _Ty>
bool _Try_lock_ref(_Ty& _LkN)
{
return _LkN.try_lock();
}
template<class _Ty>
bool _Try_lock_ref(std::reference_wrapper<_Ty> _LkN)
{
return _LkN.get().try_lock();
}
template<class _Ty>
void _Lock_from_locks(const int _Target, std::vector<_Ty>& _LkN) { // lock _LkN[_Target]
_LkN[_Target].lock();
_Lock_ref(_LkN[_Target]);
}
// FUNCTION TEMPLATE _Try_lock_from_locks
template<class _Ty>
bool _Try_lock_from_locks(const int _Target, std::vector<_Ty>& _LkN) { // try to lock _LkN[_Target]
return _LkN[_Target].try_lock();
return _Try_lock_ref(_LkN[_Target]);
}
// FUNCTION TEMPLATE _Unlock_locks
template<class _Ty>
void _Unlock_locks(int _First, int _Last, std::vector<_Ty>& _LkN) noexcept /* terminates */ {
for (; _First != _Last; ++_First) {
_LkN[_First].unlock();
_Unlock_ref(_LkN[_First]);
}
}
@@ -169,20 +200,20 @@ RESUMEF_NS
}
template <class _Lock0, class _Lock1>
bool _Lock_attempt_small(_Lock0& _Lk0, _Lock1& _Lk1)
bool _Lock_attempt_small2(_Lock0& _Lk0, _Lock1& _Lk1)
{
// attempt to lock 2 locks, by first locking _Lk0, and then trying to lock _Lk1 returns whether to try again
_Lk0.lock();
_Lock_ref(_Lk0);
try {
if (_Lk1.try_lock())
if (_Try_lock_ref(_Lk1))
return false;
}
catch (...) {
_Lk0.unlock();
_Unlock_ref(_Lk0);
throw;
}
_Lk0.unlock();
_Unlock_ref(_Lk0);
std::this_thread::yield();
return true;
}
@@ -191,7 +222,7 @@ RESUMEF_NS
void _Lock_nonmember2(_Lock0& _Lk0, _Lock1& _Lk1)
{
// lock 2 locks, without deadlock, special case for better codegen and reduced metaprogramming for common case
while (_Lock_attempt_small(_Lk0, _Lk1) && _Lock_attempt_small(_Lk1, _Lk0)) { // keep trying
while (_Lock_attempt_small2(_Lk0, _Lk1) && _Lock_attempt_small2(_Lk1, _Lk0)) { // keep trying
}
}
@@ -203,7 +234,7 @@ RESUMEF_NS
}
else if (lockes.size() == 1)
{
lockes[0].lock();
_Lock_ref(lockes[0]);
}
else if (lockes.size() == 2)
{

+ 8
- 6
tutorial/test_async_event_timeout.cpp View File

@@ -37,7 +37,7 @@ void test_wait_timeout_one()
intptr_t counter = 0;
for (;;)
{
if (co_await evt.wait_for(500ms))
if (co_await evt.wait_for(100ms))
break;
++counter;
std::cout << ".";
@@ -45,8 +45,8 @@ void test_wait_timeout_one()
std::cout << counter << std::endl;
};
async_set_event(evt, 10s + 50ms);
//go resumalbe_set_event(evt, 10s + 50ms);
async_set_event(evt, 2s + 50ms);
//go resumalbe_set_event(evt, 2s + 50ms);
this_scheduler()->run_until_notask();
}
@@ -139,7 +139,7 @@ void test_wait_timeout_all()
intptr_t counter = 0;
for (;;)
{
if (co_await event_t::wait_all_for(500ms, evts))
if (co_await event_t::wait_all_for(1500ms, evts))
{
std::cout << counter << std::endl;
std::cout << "all event signal!" << std::endl;
@@ -148,14 +148,16 @@ void test_wait_timeout_all()
++counter;
std::cout << ".";
std::cout << "timeout!" << std::endl;
break;
}
};
srand((int)time(nullptr));
for (auto & e : evts)
{
go resumalbe_set_event(e, 1ms * (1000 + rand() % 5000));
//async_set_event(e, 1ms * (1000 + rand() % 5000));
//go resumalbe_set_event(e, 1ms * (1000 + rand() % 5000));
async_set_event(e, 1ms * (1000 + rand() % 1000));
}
this_scheduler()->run_until_notask();

+ 5
- 5
tutorial/test_async_sleep.cpp View File

@@ -13,19 +13,19 @@ future_t<> test_sleep_use_timer()
{
using namespace std::chrono;
(void)resumef::sleep_for(100ms); //incorrect!!!
(void)sleep_for(100ms); //incorrect!!!
co_await resumef::sleep_for(100ms);
co_await sleep_for(100ms);
std::cout << "sleep_for 100ms." << std::endl;
co_await 100ms;
std::cout << "co_await 100ms." << std::endl;
try
{
co_await resumef::sleep_until(system_clock::now() + 200ms);
co_await sleep_until(system_clock::now() + 200ms);
std::cout << "timer after 200ms." << std::endl;
}
catch (resumef::timer_canceled_exception)
catch (timer_canceled_exception)
{
std::cout << "timer canceled." << std::endl;
}
@@ -50,7 +50,7 @@ void test_wait_all_events_with_signal_by_sleep()
{
go[&, i]() -> future_t<>
{
co_await resumef::sleep_for(1ms * (500 + rand() % 1000));
co_await sleep_for(1ms * (500 + rand() % 1000));
evts[i].signal();
std::cout << "event[ " << i << " ] signal!" << std::endl;
};

+ 2
- 2
vs_proj/librf.cpp View File

@@ -44,10 +44,10 @@ int main(int argc, const char* argv[])
//test_ring_queue<resumef::ring_queue_lockfree<int, uint64_t>>();
//resumable_main_event_v2();
resumable_main_event();
//resumable_main_event();
//resumable_main_event_timeout();
//resumable_main_sleep();
return 0;
//return 0;
//if (argc > 1)
// resumable_main_benchmark_asio_client(atoi(argv[1]));

Loading…
Cancel
Save