Browse Source

给mutex添加注释

tags/v2.9.7
tearshark 4 years ago
parent
commit
645822427d
5 changed files with 91 additions and 28 deletions
  1. 57
    4
      librf/src/mutex_v2.h
  2. 8
    0
      librf/src/mutex_v2.inl
  3. 2
    2
      librf/src/state.h
  4. 24
    21
      vs_proj/librf.cpp
  5. 0
    1
      vs_proj/librf.vcxproj

+ 57
- 4
librf/src/mutex_v2.h View File

@@ -16,6 +16,7 @@ RESUMEF_NS
struct [[nodiscard]] scoped_unlock_t;

//支持递归的锁
//锁被本协程所在的跟协程所拥有。支持在跟协程下的所有协程里递归加锁。
struct mutex_t
{
bool is_locked() const;
@@ -24,24 +25,57 @@ RESUMEF_NS
struct [[nodiscard]] awaiter;
struct [[nodiscard]] manual_awaiter;

/**
* @brief 在协程中加锁。
* @return [co_await] scoped_unlock_t
*/
awaiter/*scoped_unlock_t*/ lock() const noexcept;
/**
* @brief 等同调用co_await lock()。
* @return [co_await] scoped_unlock_t
*/
awaiter/*scoped_unlock_t*/ operator co_await() const noexcept;

/**
* @brief 在协程中加锁。需要随后调用unlock()函数解锁。lock()/unlock()调用必须在同一个跟协程下配对调用。
* @return [co_await] void
*/
manual_awaiter/*void*/ lock(adopt_manual_unlock_t) const noexcept;

struct [[nodiscard]] try_awaiter;
//co_await try_lock()获得是否加锁成功。此操作无论成功与否都会立即返回。
//如果加锁成功,则需要调用co_await unlock()解锁。或者使用unlock(root_state())解锁。
//如果加锁失败,且要循环尝试加锁,则最好调用co_await yield()让出一次调度。否则,可能造成本调度器死循环。
/**
* @brief 尝试在协程中加锁。此操作无论成功与否都会立即返回。
* 如果加锁成功,则需要调用co_await unlock()解锁。或者使用unlock(root_state())解锁。
* 如果加锁失败,且要循环尝试加锁,则最好调用co_await yield()让出一次调度。否则,可能造成本调度器死循环。
* @return [co_await] bool
*/
try_awaiter/*bool*/ try_lock() const noexcept;

//此操作立即返回
/**
* @brief 在协程中解锁。此操作立即返回。
* @return [co_await] void
*/
struct [[nodiscard]] unlock_awaiter;
unlock_awaiter/*void*/ unlock() const noexcept;


struct [[nodiscard]] timeout_awaiter;

/**
* @brief 在协程中尝试加锁,直到超时
* @param dt 超时时长
* @return [co_await] bool
*/
template <class _Rep, class _Period>
timeout_awaiter/*bool*/ try_lock_for(const std::chrono::duration<_Rep, _Period>& dt) const noexcept;

/**
* @brief 在协程中尝试加锁,直到超时
* @param tp 超时时刻
* @return [co_await] bool
*/
template <class _Rep, class _Period>
timeout_awaiter/*bool*/ try_lock_until(const std::chrono::time_point<_Rep, _Period>& tp) const noexcept;

@@ -55,17 +89,36 @@ RESUMEF_NS
void unlock(void* unique_address) const;


/**
* @brief 在协程中,无死锁的批量加锁。捕获阻塞当前线程。直到获得所有锁之前,阻塞当前协程。
* @return [co_await] scoped_unlock_t
*/
template<class... _Mtxs
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>>
>
static future_t<scoped_unlock_t<_Mtxs...>> lock(_Mtxs&... mtxs);


/**
* @brief 在非协程中,无死锁的批量加锁。会阻塞当前线程,直到获得所有锁为止。
* @return scoped_unlock_t
*/
template<class... _Mtxs
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>>
>
static scoped_unlock_t<_Mtxs...> lock(void* unique_address, _Mtxs&... mtxs);

/**
* @brief 在非协程中,无死锁的批量加锁。会阻塞当前线程,直到获得所有锁为止。
*/
template<class... _Mtxs
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>>
>
static void lock(adopt_manual_unlock_t, void* unique_address, _Mtxs&... mtxs);

/**
* @brief 在非协程中,批量解锁加锁。立即返回。
*/
template<class... _Mtxs
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>>
>

+ 8
- 0
librf/src/mutex_v2.inl View File

@@ -547,6 +547,14 @@ RESUMEF_NS
return { unique_address, mtxs... };
}

template<class... _Mtxs, typename>
inline void mutex_t::lock(adopt_manual_unlock_t, void* unique_address, _Mtxs&... mtxs)
{
assert(unique_address != nullptr);
mutex_t::_MutexAwaitAssembleT _MAA{ unique_address, mtxs... };
detail::scoped_lock_range_lock_impl::_Lock_range(_MAA);
}

template<class... _Mtxs, typename>
inline void mutex_t::unlock(void* unique_address, _Mtxs&... mtxs)
{

+ 2
- 2
librf/src/state.h View File

@@ -178,7 +178,7 @@ RESUMEF_NS
static _Sty* _Construct(void* _Ptr, size_t _Size)
{
_Sty* st = new(_Ptr) _Sty(false);
st->_alloc_size = _Size;
st->_alloc_size = static_cast<uint32_t>(_Size);
return st;
}
@@ -193,7 +193,7 @@ RESUMEF_NS
#endif
char* _Ptr = _Al.allocate(_Size);
_Sty* st = new(_Ptr) _Sty(awaitor);
st->_alloc_size = _Size;
st->_alloc_size = static_cast<uint32_t>(_Size);
return st;
}

+ 24
- 21
vs_proj/librf.cpp View File

@@ -1,6 +1,7 @@

#include "librf.h"
#include <optional>
#include <crtdbg.h>
//#define _WITH_LOCK_FREE_Q_KEEP_REAL_SIZE 1
#include "src/ring_queue.h"
@@ -36,6 +37,7 @@ extern void resumable_main_benchmark_asio_client(intptr_t nNum);
int main(int argc, const char* argv[])
{
//_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF);
(void)argc;
(void)argv;
@@ -51,30 +53,31 @@ int main(int argc, const char* argv[])
//else
// resumable_main_benchmark_asio_server();
resumable_main_cb();
resumable_main_layout();
resumable_main_modern_cb();
resumable_main_suspend_always();
resumable_main_yield_return();
resumable_main_resumable();
resumable_main_routine();
resumable_main_exception();
resumable_main_dynamic_go();
resumable_main_multi_thread();
resumable_main_timer();
resumable_main_benchmark_mem(false);
resumable_main_mutex();
resumable_main_event();
resumable_main_event_v2();
resumable_main_event_timeout();
resumable_main_channel();
resumable_main_channel_mult_thread();
resumable_main_sleep();
resumable_main_when_all();
resumable_main_switch_scheduler();
resumable_main_cb(); _CrtCheckMemory();
resumable_main_layout(); _CrtCheckMemory();
resumable_main_modern_cb(); _CrtCheckMemory();
resumable_main_suspend_always(); _CrtCheckMemory();
resumable_main_yield_return(); _CrtCheckMemory();
resumable_main_resumable(); _CrtCheckMemory();
resumable_main_routine(); _CrtCheckMemory();
resumable_main_exception(); _CrtCheckMemory();
resumable_main_dynamic_go(); _CrtCheckMemory();
resumable_main_multi_thread(); _CrtCheckMemory();
resumable_main_timer(); _CrtCheckMemory();
resumable_main_benchmark_mem(false); _CrtCheckMemory();
resumable_main_mutex(); _CrtCheckMemory();
resumable_main_event(); _CrtCheckMemory();
resumable_main_event_v2(); _CrtCheckMemory();
resumable_main_event_timeout(); _CrtCheckMemory();
resumable_main_channel(); _CrtCheckMemory();
resumable_main_channel_mult_thread(); _CrtCheckMemory();
resumable_main_sleep(); _CrtCheckMemory();
resumable_main_when_all(); _CrtCheckMemory();
resumable_main_switch_scheduler(); _CrtCheckMemory();
std::cout << "ALL OK!" << std::endl;
benchmark_main_channel_passing_next(); //这是一个死循环测试
_CrtCheckMemory();
return 0;
}

+ 0
- 1
vs_proj/librf.vcxproj View File

@@ -37,7 +37,6 @@
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
<EnableASAN>true</EnableASAN>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>

Loading…
Cancel
Save