дзеркало
https://github.com/tearshark/librf.git
synced 2024-10-01 15:57:07 +08:00
审查mutex_v2代码
This commit is contained in:
джерело
9d94bfa30c
коміт
6fef43340a
@ -358,6 +358,7 @@ inline namespace channel_v2
|
||||
|
||||
read_awaiter(channel_type* ch) noexcept
|
||||
: _channel(ch)
|
||||
, _value()
|
||||
{}
|
||||
|
||||
~read_awaiter()
|
||||
|
@ -219,11 +219,9 @@ RESUMEF_NS
|
||||
clock_type::time_point _tp;
|
||||
};
|
||||
|
||||
struct [[nodiscard]] event_t::timeout_awaiter : timeout_awaitor_impl<event_t::awaiter>
|
||||
struct [[nodiscard]] event_t::timeout_awaiter : timeout_awaitor_impl<awaiter>
|
||||
{
|
||||
timeout_awaiter(clock_type::time_point tp, detail::event_v2_impl* evt) noexcept
|
||||
: timeout_awaitor_impl<event_t::awaiter>(tp, evt)
|
||||
{}
|
||||
using timeout_awaitor_impl<awaiter>::timeout_awaitor_impl;
|
||||
};
|
||||
|
||||
template<class _Rep, class _Period>
|
||||
@ -331,11 +329,9 @@ RESUMEF_NS
|
||||
|
||||
|
||||
template<class _Iter>
|
||||
struct [[nodiscard]] event_t::timeout_any_awaiter : timeout_awaitor_impl<event_t::any_awaiter<_Iter>>
|
||||
struct [[nodiscard]] event_t::timeout_any_awaiter : timeout_awaitor_impl<any_awaiter<_Iter>>
|
||||
{
|
||||
timeout_any_awaiter(clock_type::time_point tp, _Iter begin, _Iter end) noexcept
|
||||
: timeout_awaitor_impl<event_t::any_awaiter<_Iter>>(tp, begin, end)
|
||||
{}
|
||||
using timeout_awaitor_impl<any_awaiter<_Iter>>::timeout_awaitor_impl;
|
||||
};
|
||||
|
||||
template<class _Rep, class _Period, class _Iter COMMA_RESUMEF_ENABLE_IF_TYPENAME()>
|
||||
@ -445,11 +441,9 @@ RESUMEF_NS
|
||||
|
||||
|
||||
template<class _Iter>
|
||||
struct [[nodiscard]] event_t::timeout_all_awaiter : timeout_awaitor_impl<event_t::all_awaiter<_Iter>>
|
||||
struct [[nodiscard]] event_t::timeout_all_awaiter : timeout_awaitor_impl<all_awaiter<_Iter>>
|
||||
{
|
||||
timeout_all_awaiter(clock_type::time_point tp, _Iter begin, _Iter end) noexcept
|
||||
: timeout_awaitor_impl<event_t::all_awaiter<_Iter>>(tp, begin, end)
|
||||
{}
|
||||
using timeout_awaitor_impl<all_awaiter<_Iter>>::timeout_awaitor_impl;
|
||||
};
|
||||
|
||||
template<class _Rep, class _Period, class _Iter COMMA_RESUMEF_ENABLE_IF_TYPENAME()>
|
||||
|
@ -4,7 +4,7 @@ RESUMEF_NS
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
void state_mutex_base_t::resume()
|
||||
void state_mutex_t::resume()
|
||||
{
|
||||
coroutine_handle<> handler = _coro;
|
||||
if (handler)
|
||||
@ -15,12 +15,12 @@ RESUMEF_NS
|
||||
}
|
||||
}
|
||||
|
||||
bool state_mutex_base_t::has_handler() const noexcept
|
||||
bool state_mutex_t::has_handler() const noexcept
|
||||
{
|
||||
return (bool)_coro;
|
||||
}
|
||||
|
||||
state_base_t* state_mutex_base_t::get_parent() const noexcept
|
||||
state_base_t* state_mutex_t::get_parent() const noexcept
|
||||
{
|
||||
return _root;
|
||||
}
|
||||
@ -74,59 +74,18 @@ RESUMEF_NS
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void state_mutex_all_t::on_cancel() noexcept
|
||||
void state_mutex_t::add_timeout_timer(std::chrono::system_clock::time_point tp)
|
||||
{
|
||||
intptr_t oldValue = _counter.load(std::memory_order_acquire);
|
||||
if (oldValue >= 0 && _counter.compare_exchange_strong(oldValue, -1, std::memory_order_acq_rel))
|
||||
this->_thandler = this->_scheduler->timer()->add_handler(tp,
|
||||
[st = counted_ptr<state_mutex_t>{ this }](bool canceld)
|
||||
{
|
||||
*_value = false;
|
||||
_thandler.stop();
|
||||
|
||||
this->_coro = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool state_mutex_all_t::on_notify(event_v2_impl*)
|
||||
{
|
||||
intptr_t oldValue = _counter.load(std::memory_order_acquire);
|
||||
if (oldValue <= 0) return false;
|
||||
|
||||
oldValue = _counter.fetch_add(-1, std::memory_order_acq_rel);
|
||||
if (oldValue == 1)
|
||||
{
|
||||
*_value = true;
|
||||
_thandler.stop();
|
||||
|
||||
assert(this->_scheduler != nullptr);
|
||||
if (this->_coro)
|
||||
this->_scheduler->add_generator(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return oldValue >= 1;
|
||||
}
|
||||
|
||||
bool state_mutex_all_t::on_timeout()
|
||||
{
|
||||
intptr_t oldValue = _counter.load(std::memory_order_acquire);
|
||||
if (oldValue >= 0 && _counter.compare_exchange_strong(oldValue, -1, std::memory_order_acq_rel))
|
||||
{
|
||||
*_value = false;
|
||||
_thandler.reset();
|
||||
|
||||
assert(this->_scheduler != nullptr);
|
||||
if (this->_coro)
|
||||
this->_scheduler->add_generator(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (!canceld)
|
||||
st->on_timeout();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void mutex_v2_impl::lock_until_succeed(void* sch)
|
||||
{
|
||||
assert(sch != nullptr);
|
||||
@ -164,16 +123,16 @@ RESUMEF_NS
|
||||
{
|
||||
assert(sch != nullptr);
|
||||
|
||||
void* oldValue = _owner.load(std::memory_order_acquire);
|
||||
void* oldValue = _owner.load(std::memory_order_relaxed);
|
||||
if (oldValue == nullptr)
|
||||
{
|
||||
_owner.store(sch, std::memory_order_release);
|
||||
_counter.fetch_add(1, std::memory_order_acq_rel);
|
||||
_owner.store(sch, std::memory_order_relaxed);
|
||||
_counter.fetch_add(1, std::memory_order_relaxed);
|
||||
return true;
|
||||
}
|
||||
if (oldValue == sch)
|
||||
{
|
||||
_counter.fetch_add(1, std::memory_order_acq_rel);
|
||||
_counter.fetch_add(1, std::memory_order_relaxed);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -185,12 +144,13 @@ RESUMEF_NS
|
||||
|
||||
scoped_lock<lock_type> lock_(_lock);
|
||||
|
||||
void* oldValue = _owner.load(std::memory_order_acquire);
|
||||
void* oldValue = _owner.load(std::memory_order_relaxed);
|
||||
if (oldValue == sch)
|
||||
{
|
||||
if (_counter.fetch_sub(1, std::memory_order_acquire) == 1)
|
||||
if (_counter.fetch_sub(1, std::memory_order_relaxed) == 1)
|
||||
{
|
||||
_owner.store(nullptr, std::memory_order_release);
|
||||
_owner.store(nullptr, std::memory_order_relaxed);
|
||||
|
||||
while (!_wait_awakes.empty())
|
||||
{
|
||||
state_mutex_ptr state = _wait_awakes.front();
|
||||
@ -204,8 +164,8 @@ RESUMEF_NS
|
||||
break;
|
||||
|
||||
//转移状态失败,恢复成空
|
||||
_owner.store(nullptr, std::memory_order_release);
|
||||
_counter.fetch_sub(1, std::memory_order_acq_rel);
|
||||
_owner.store(nullptr, std::memory_order_relaxed);
|
||||
_counter.fetch_sub(1, std::memory_order_relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,16 +4,22 @@ RESUMEF_NS
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct state_mutex_base_t : public state_base_t
|
||||
struct state_mutex_t : public state_base_t
|
||||
{
|
||||
state_mutex_t(mutex_v2_impl*& val)
|
||||
: _value(&val)
|
||||
{}
|
||||
|
||||
virtual void resume() override;
|
||||
virtual bool has_handler() const noexcept override;
|
||||
virtual state_base_t* get_parent() const noexcept override;
|
||||
|
||||
virtual void on_cancel() noexcept = 0;
|
||||
virtual bool on_notify(mutex_v2_impl* eptr) = 0;
|
||||
virtual bool on_timeout() = 0;
|
||||
|
||||
void on_cancel() noexcept;
|
||||
bool on_notify(mutex_v2_impl* eptr);
|
||||
bool on_timeout();
|
||||
|
||||
void add_timeout_timer(std::chrono::system_clock::time_point tp);
|
||||
|
||||
inline scheduler_t* get_scheduler() const noexcept
|
||||
{
|
||||
return _scheduler;
|
||||
@ -26,62 +32,22 @@ RESUMEF_NS
|
||||
this->_root = root;
|
||||
}
|
||||
|
||||
inline void add_timeout_timer(std::chrono::system_clock::time_point tp)
|
||||
{
|
||||
this->_thandler = this->_scheduler->timer()->add_handler(tp,
|
||||
[st = counted_ptr<state_mutex_base_t>{ this }](bool canceld)
|
||||
{
|
||||
if (!canceld)
|
||||
st->on_timeout();
|
||||
});
|
||||
}
|
||||
|
||||
timer_handler _thandler;
|
||||
protected:
|
||||
state_base_t* _root;
|
||||
};
|
||||
|
||||
struct state_mutex_t : public state_mutex_base_t
|
||||
{
|
||||
state_mutex_t(mutex_v2_impl*& val)
|
||||
: _value(&val)
|
||||
{}
|
||||
|
||||
virtual void on_cancel() noexcept override;
|
||||
virtual bool on_notify(mutex_v2_impl* eptr) override;
|
||||
virtual bool on_timeout() override;
|
||||
public:
|
||||
timer_handler _thandler;
|
||||
protected:
|
||||
std::atomic<mutex_v2_impl**> _value;
|
||||
};
|
||||
|
||||
struct state_mutex_all_t : public state_event_base_t
|
||||
{
|
||||
state_mutex_all_t(intptr_t count, bool& val)
|
||||
: _counter(count)
|
||||
, _value(&val)
|
||||
{}
|
||||
|
||||
virtual void on_cancel() noexcept override;
|
||||
virtual bool on_notify(event_v2_impl* eptr) override;
|
||||
virtual bool on_timeout() override;
|
||||
public:
|
||||
timer_handler _thandler;
|
||||
std::atomic<intptr_t> _counter;
|
||||
protected:
|
||||
bool* _value;
|
||||
};
|
||||
|
||||
struct mutex_v2_impl : public std::enable_shared_from_this<mutex_v2_impl>
|
||||
{
|
||||
using clock_type = std::chrono::system_clock;
|
||||
|
||||
mutex_v2_impl() {}
|
||||
|
||||
inline void* owner() const noexcept
|
||||
inline void* owner() noexcept
|
||||
{
|
||||
return _owner.load(std::memory_order_acquire);
|
||||
scoped_lock<lock_type> lock_(_lock);
|
||||
return _owner.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
bool try_lock(void* sch); //内部加锁
|
||||
@ -171,7 +137,9 @@ RESUMEF_NS
|
||||
{
|
||||
typedef std::shared_ptr<detail::mutex_v2_impl> mutex_impl_ptr;
|
||||
|
||||
scoped_unlock_t() {}
|
||||
scoped_unlock_t()
|
||||
: _owner(nullptr)
|
||||
{}
|
||||
|
||||
//此函数,应该在try_lock()获得锁后使用
|
||||
//或者在协程里,由awaiter使用
|
||||
@ -405,12 +373,9 @@ RESUMEF_NS
|
||||
|
||||
|
||||
|
||||
struct [[nodiscard]] mutex_t::timeout_awaiter : public event_t::timeout_awaitor_impl<awaiter>
|
||||
struct [[nodiscard]] mutex_t::timeout_awaiter : public event_t::timeout_awaitor_impl<lock_awaiter>
|
||||
{
|
||||
timeout_awaiter(clock_type::time_point tp, detail::mutex_v2_impl * mtx) noexcept
|
||||
: event_t::timeout_awaitor_impl<mutex_t::awaiter>(tp, mtx)
|
||||
{}
|
||||
|
||||
using event_t::timeout_awaitor_impl<lock_awaiter>::timeout_awaitor_impl;
|
||||
bool await_resume() noexcept
|
||||
{
|
||||
detail::mutex_v2_impl* mtx = this->_mutex;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
RESUMEF_NS
|
||||
{
|
||||
future_t<> sleep_until_(const std::chrono::system_clock::time_point& tp_, scheduler_t& scheduler_)
|
||||
future_t<> sleep_until_(std::chrono::system_clock::time_point tp_, scheduler_t& scheduler_)
|
||||
{
|
||||
awaitable_t<> awaitable;
|
||||
|
||||
|
@ -8,32 +8,32 @@ RESUMEF_NS
|
||||
{
|
||||
struct scheduler_t;
|
||||
|
||||
future_t<> sleep_until_(const std::chrono::system_clock::time_point& tp_, scheduler_t& scheduler_);
|
||||
future_t<> sleep_until_(std::chrono::system_clock::time_point tp_, scheduler_t& scheduler_);
|
||||
|
||||
inline future_t<> sleep_for_(const std::chrono::system_clock::duration& dt_, scheduler_t& scheduler_)
|
||||
inline future_t<> sleep_for_(std::chrono::system_clock::duration dt_, scheduler_t& scheduler_)
|
||||
{
|
||||
return sleep_until_(std::chrono::system_clock::now() + dt_, scheduler_);
|
||||
}
|
||||
|
||||
template<class _Rep, class _Period>
|
||||
inline future_t<> sleep_for(const std::chrono::duration<_Rep, _Period>& dt_, scheduler_t& scheduler_)
|
||||
inline future_t<> sleep_for(std::chrono::duration<_Rep, _Period> dt_, scheduler_t& scheduler_)
|
||||
{
|
||||
return sleep_for_(std::chrono::duration_cast<std::chrono::system_clock::duration>(dt_), scheduler_);
|
||||
}
|
||||
|
||||
template<class _Clock, class _Duration = typename _Clock::duration>
|
||||
inline future_t<> sleep_until(const std::chrono::time_point<_Clock, _Duration>& tp_, scheduler_t& scheduler_)
|
||||
inline future_t<> sleep_until(std::chrono::time_point<_Clock, _Duration> tp_, scheduler_t& scheduler_)
|
||||
{
|
||||
return sleep_until_(std::chrono::time_point_cast<std::chrono::system_clock::duration>(tp_), scheduler_);
|
||||
}
|
||||
|
||||
template<class _Rep, class _Period>
|
||||
inline future_t<> sleep_for(const std::chrono::duration<_Rep, _Period>& dt_)
|
||||
inline future_t<> sleep_for(std::chrono::duration<_Rep, _Period> dt_)
|
||||
{
|
||||
co_await sleep_for_(std::chrono::duration_cast<std::chrono::system_clock::duration>(dt_), *current_scheduler());
|
||||
}
|
||||
template<class _Clock, class _Duration>
|
||||
inline future_t<> sleep_until(const std::chrono::time_point<_Clock, _Duration>& tp_)
|
||||
inline future_t<> sleep_until(std::chrono::time_point<_Clock, _Duration> tp_)
|
||||
{
|
||||
co_await sleep_until_(std::chrono::time_point_cast<std::chrono::system_clock::duration>(tp_), *current_scheduler());
|
||||
}
|
||||
|
@ -323,7 +323,9 @@ inline namespace when_v2
|
||||
auto when_any(scheduler_t& sch, _Awaitable&&... args)
|
||||
-> detail::when_future_t<when_any_pair>
|
||||
{
|
||||
#pragma warning(disable : 6326) //warning C6326: Potential comparison of a constant with another constant.
|
||||
detail::when_future_t<when_any_pair> awaitor{ sizeof...(_Awaitable) > 0 ? 1 : 0 };
|
||||
#pragma warning(default : 6326)
|
||||
awaitor._values->first = -1;
|
||||
detail::when_any_one__(sch, awaitor._state.get(), awaitor._values, 0, std::forward<_Awaitable>(args)...);
|
||||
|
||||
|
@ -143,7 +143,7 @@ static void resumable_mutex_async()
|
||||
|
||||
static future_t<> resumable_mutex_range_push(size_t idx, mutex_t a, mutex_t b, mutex_t c)
|
||||
{
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
{
|
||||
scoped_unlock_t __lockers = co_await mutex_t::lock(a, b, c);
|
||||
assert(a.is_locked());
|
||||
@ -159,7 +159,7 @@ static future_t<> resumable_mutex_range_push(size_t idx, mutex_t a, mutex_t b, m
|
||||
|
||||
static future_t<> resumable_mutex_range_pop(size_t idx, mutex_t a, mutex_t b, mutex_t c)
|
||||
{
|
||||
for (int i = 0; i < 1000; ++i)
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
{
|
||||
scoped_unlock_t __lockers = co_await mutex_t::lock(a, b, c);
|
||||
assert(a.is_locked());
|
||||
|
@ -43,8 +43,8 @@ int main(int argc, const char* argv[])
|
||||
//test_ring_queue<resumef::ring_queue_spinlock<int, false, uint32_t>>();
|
||||
//test_ring_queue<resumef::ring_queue_lockfree<int, uint64_t>>();
|
||||
|
||||
resumable_main_mutex();
|
||||
return 0;
|
||||
//resumable_main_mutex();
|
||||
//return 0;
|
||||
|
||||
//if (argc > 1)
|
||||
// resumable_main_benchmark_asio_client(atoi(argv[1]));
|
||||
|
@ -46,7 +46,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>ClangCL</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@ -77,7 +77,6 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<CodeAnalysisRuleSet>NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<EnableClangTidyCodeAnalysis>true</EnableClangTidyCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@ -158,7 +157,7 @@
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<SDLCheck>
|
||||
</SDLCheck>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<EnablePREfast>true</EnablePREfast>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
|
||||
|
Завантаження…
Посилання в новій задачі
Block a user