mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-11-30 02:47:56 +08:00
Add C++ API for fiber mutex deadlock checking.
This commit is contained in:
parent
758dd3852a
commit
3ef3fa8128
@ -32,7 +32,7 @@ typedef struct ACL_FIBER_MUTEX_STATS {
|
|||||||
|
|
||||||
|
|
||||||
FIBER_API void acl_fiber_mutex_profile(void);
|
FIBER_API void acl_fiber_mutex_profile(void);
|
||||||
FIBER_API ACL_FIBER_MUTEX_STATS *acl_fiber_mutex_deadcheck(void);
|
FIBER_API ACL_FIBER_MUTEX_STATS *acl_fiber_mutex_deadlock(void);
|
||||||
FIBER_API void acl_fiber_mutex_stats_free(ACL_FIBER_MUTEX_STATS *stats);
|
FIBER_API void acl_fiber_mutex_stats_free(ACL_FIBER_MUTEX_STATS *stats);
|
||||||
FIBER_API void acl_fiber_mutex_stats_show(const ACL_FIBER_MUTEX_STATS *stats);
|
FIBER_API void acl_fiber_mutex_stats_show(const ACL_FIBER_MUTEX_STATS *stats);
|
||||||
|
|
||||||
|
@ -259,7 +259,6 @@ static ACL_FIBER_MUTEX_STATS *check_deadlock2(MUTEX_CHECK *check)
|
|||||||
SNPRINTF(hkey, sizeof(hkey), "%d", acl_fiber_id(fiber));
|
SNPRINTF(hkey, sizeof(hkey), "%d", acl_fiber_id(fiber));
|
||||||
if (htable_find(table, hkey) != NULL) {
|
if (htable_find(table, hkey) != NULL) {
|
||||||
deadlocked = 1;
|
deadlocked = 1;
|
||||||
printf("DeadLock happened!\r\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -314,7 +313,7 @@ static ACL_FIBER_MUTEX_STATS *check_deadlock(THREAD_MUTEXES *mutexes)
|
|||||||
return stats;
|
return stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
ACL_FIBER_MUTEX_STATS *acl_fiber_mutex_deadcheck(void)
|
ACL_FIBER_MUTEX_STATS *acl_fiber_mutex_deadlock(void)
|
||||||
{
|
{
|
||||||
if (__locks != NULL) {
|
if (__locks != NULL) {
|
||||||
ACL_FIBER_MUTEX_STATS *stats;
|
ACL_FIBER_MUTEX_STATS *stats;
|
||||||
|
@ -17,9 +17,8 @@ typedef enum
|
|||||||
FIBER_EVENT_T_IO_URING, // Linux
|
FIBER_EVENT_T_IO_URING, // Linux
|
||||||
} fiber_event_t;
|
} fiber_event_t;
|
||||||
|
|
||||||
class FIBER_CPP_API fiber_frame
|
struct FIBER_CPP_API fiber_frame
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
fiber_frame(void) : pc(0), off(0) {}
|
fiber_frame(void) : pc(0), off(0) {}
|
||||||
~fiber_frame(void) {}
|
~fiber_frame(void) {}
|
||||||
|
|
||||||
@ -34,6 +33,9 @@ public:
|
|||||||
class FIBER_CPP_API fiber
|
class FIBER_CPP_API fiber
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
fiber(void);
|
||||||
|
fiber(ACL_FIBER *fb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造函数
|
* 构造函数
|
||||||
* @param running {bool} 当为 true 时,则表示当前协程已启动,仅是声明
|
* @param running {bool} 当为 true 时,则表示当前协程已启动,仅是声明
|
||||||
@ -41,7 +43,8 @@ public:
|
|||||||
* 象的 start 方法启动新协程; 当为 false 时,则需要调用 start 方法来
|
* 象的 start 方法启动新协程; 当为 false 时,则需要调用 start 方法来
|
||||||
* 启动新协程
|
* 启动新协程
|
||||||
*/
|
*/
|
||||||
fiber(bool running = false);
|
fiber(bool running);
|
||||||
|
|
||||||
virtual ~fiber(void);
|
virtual ~fiber(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,6 +90,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
static unsigned int self(void);
|
static unsigned int self(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得指定协程对象的ID号
|
||||||
|
* @return {unsigned int}
|
||||||
|
*/
|
||||||
|
static unsigned int id(const fiber& fb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得当前协程在执行某个系统 API 出错时的错误号
|
* 获得当前协程在执行某个系统 API 出错时的错误号
|
||||||
* return {int}
|
* return {int}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <vector>
|
||||||
#include "fiber_cpp_define.hpp"
|
#include "fiber_cpp_define.hpp"
|
||||||
|
#include "fiber_mutex_stat.hpp"
|
||||||
|
|
||||||
struct ACL_FIBER_MUTEX;
|
struct ACL_FIBER_MUTEX;
|
||||||
|
|
||||||
@ -12,7 +14,13 @@ namespace acl {
|
|||||||
class FIBER_CPP_API fiber_mutex
|
class FIBER_CPP_API fiber_mutex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
fiber_mutex(void);
|
/**
|
||||||
|
* 构造函数
|
||||||
|
* @param mutex {ACL_FIBER_MUTEX*} 非空时,将用 C 的锁对象创建 C++ 锁
|
||||||
|
* 对象,否则内部自动创建 C 锁对象;如果非空时,在本对象析构时该传入的
|
||||||
|
* C 锁对象需由应用层自行释放.
|
||||||
|
*/
|
||||||
|
fiber_mutex(ACL_FIBER_MUTEX* mutex = NULL);
|
||||||
~fiber_mutex(void);
|
~fiber_mutex(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,8 +51,16 @@ public:
|
|||||||
return mutex_;
|
return mutex_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进行全局死锁检测
|
||||||
|
* @param out {fiber_mutex_stats&} 存储结果集
|
||||||
|
* @return {bool} 返回 true 表示存在死锁问题, 死锁信息存放在 out 中
|
||||||
|
*/
|
||||||
|
static bool deadlock(fiber_mutex_stats& out);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ACL_FIBER_MUTEX* mutex_;
|
ACL_FIBER_MUTEX* mutex_;
|
||||||
|
ACL_FIBER_MUTEX* mutex_internal_;
|
||||||
|
|
||||||
fiber_mutex(const fiber_mutex&);
|
fiber_mutex(const fiber_mutex&);
|
||||||
void operator=(const fiber_mutex&);
|
void operator=(const fiber_mutex&);
|
||||||
|
27
lib_fiber/cpp/include/fiber/fiber_mutex_stat.hpp
Normal file
27
lib_fiber/cpp/include/fiber/fiber_mutex_stat.hpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct ACL_FIBER_MUTEX;
|
||||||
|
|
||||||
|
namespace acl {
|
||||||
|
|
||||||
|
class fiber;
|
||||||
|
|
||||||
|
struct FIBER_CPP_API fiber_mutex_stat
|
||||||
|
{
|
||||||
|
fiber_mutex_stat(void) : fb(NULL), waiting(NULL) {}
|
||||||
|
~fiber_mutex_stat(void) {}
|
||||||
|
|
||||||
|
fiber *fb;
|
||||||
|
ACL_FIBER_MUTEX *waiting;
|
||||||
|
std::vector<ACL_FIBER_MUTEX*> holding;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FIBER_CPP_API fiber_mutex_stats
|
||||||
|
{
|
||||||
|
fiber_mutex_stats(void) {}
|
||||||
|
~fiber_mutex_stats(void);
|
||||||
|
|
||||||
|
std::vector<fiber_mutex_stat> stats;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace acl
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include "fiber_lock.hpp"
|
#include "fiber_lock.hpp"
|
||||||
#include "fiber_event.hpp"
|
#include "fiber_event.hpp"
|
||||||
|
#include "fiber_mutex.hpp"
|
||||||
|
#include "fiber_mutex_stat.hpp"
|
||||||
#include "fiber_cond.hpp"
|
#include "fiber_cond.hpp"
|
||||||
#include "wait_group.hpp"
|
#include "wait_group.hpp"
|
||||||
#include "fiber_sem.hpp"
|
#include "fiber_sem.hpp"
|
||||||
|
@ -315,6 +315,8 @@
|
|||||||
<ClInclude Include="include\fiber\fiber_cpp_define.hpp" />
|
<ClInclude Include="include\fiber\fiber_cpp_define.hpp" />
|
||||||
<ClInclude Include="include\fiber\fiber_event.hpp" />
|
<ClInclude Include="include\fiber\fiber_event.hpp" />
|
||||||
<ClInclude Include="include\fiber\fiber_lock.hpp" />
|
<ClInclude Include="include\fiber\fiber_lock.hpp" />
|
||||||
|
<ClInclude Include="include\fiber\fiber_mutex.hpp" />
|
||||||
|
<ClInclude Include="include\fiber\fiber_mutex_stat.hpp" />
|
||||||
<ClInclude Include="include\fiber\fiber_redis_pipeline.hpp" />
|
<ClInclude Include="include\fiber\fiber_redis_pipeline.hpp" />
|
||||||
<ClInclude Include="include\fiber\fiber_sem.hpp" />
|
<ClInclude Include="include\fiber\fiber_sem.hpp" />
|
||||||
<ClInclude Include="include\fiber\fiber_tbox.hpp" />
|
<ClInclude Include="include\fiber\fiber_tbox.hpp" />
|
||||||
@ -331,6 +333,8 @@
|
|||||||
<ClCompile Include="src\fiber_cond.cpp" />
|
<ClCompile Include="src\fiber_cond.cpp" />
|
||||||
<ClCompile Include="src\fiber_event.cpp" />
|
<ClCompile Include="src\fiber_event.cpp" />
|
||||||
<ClCompile Include="src\fiber_lock.cpp" />
|
<ClCompile Include="src\fiber_lock.cpp" />
|
||||||
|
<ClCompile Include="src\fiber_mutex.cpp" />
|
||||||
|
<ClCompile Include="src\fiber_mutex_stat.cpp" />
|
||||||
<ClCompile Include="src\fiber_redis_pipeline.cpp" />
|
<ClCompile Include="src\fiber_redis_pipeline.cpp" />
|
||||||
<ClCompile Include="src\fiber_sem.cpp" />
|
<ClCompile Include="src\fiber_sem.cpp" />
|
||||||
<ClCompile Include="src\fiber_server.cpp" />
|
<ClCompile Include="src\fiber_server.cpp" />
|
||||||
|
@ -45,6 +45,12 @@
|
|||||||
<ClInclude Include="include\fiber\fiber_lock.hpp">
|
<ClInclude Include="include\fiber\fiber_lock.hpp">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\fiber\fiber_mutex.hpp">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\fiber\fiber_mutex_stat.hpp">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="include\fiber\fiber_redis_pipeline.hpp">
|
<ClInclude Include="include\fiber\fiber_redis_pipeline.hpp">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -83,6 +89,12 @@
|
|||||||
<ClCompile Include="src\fiber_lock.cpp">
|
<ClCompile Include="src\fiber_lock.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\fiber_mutex.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\fiber_mutex_stat.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="src\fiber_redis_pipeline.cpp">
|
<ClCompile Include="src\fiber_redis_pipeline.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -309,6 +309,8 @@
|
|||||||
<ClInclude Include="include\fiber\fiber_cpp_define.hpp" />
|
<ClInclude Include="include\fiber\fiber_cpp_define.hpp" />
|
||||||
<ClInclude Include="include\fiber\fiber_event.hpp" />
|
<ClInclude Include="include\fiber\fiber_event.hpp" />
|
||||||
<ClInclude Include="include\fiber\fiber_lock.hpp" />
|
<ClInclude Include="include\fiber\fiber_lock.hpp" />
|
||||||
|
<ClInclude Include="include\fiber\fiber_mutex.hpp" />
|
||||||
|
<ClInclude Include="include\fiber\fiber_mutex_stat.hpp" />
|
||||||
<ClInclude Include="include\fiber\fiber_redis_pipeline.hpp" />
|
<ClInclude Include="include\fiber\fiber_redis_pipeline.hpp" />
|
||||||
<ClInclude Include="include\fiber\fiber_sem.hpp" />
|
<ClInclude Include="include\fiber\fiber_sem.hpp" />
|
||||||
<ClInclude Include="include\fiber\fiber_tbox.hpp" />
|
<ClInclude Include="include\fiber\fiber_tbox.hpp" />
|
||||||
@ -325,6 +327,8 @@
|
|||||||
<ClCompile Include="src\fiber_cond.cpp" />
|
<ClCompile Include="src\fiber_cond.cpp" />
|
||||||
<ClCompile Include="src\fiber_event.cpp" />
|
<ClCompile Include="src\fiber_event.cpp" />
|
||||||
<ClCompile Include="src\fiber_lock.cpp" />
|
<ClCompile Include="src\fiber_lock.cpp" />
|
||||||
|
<ClCompile Include="src\fiber_mutex.cpp" />
|
||||||
|
<ClCompile Include="src\fiber_mutex_stat.cpp" />
|
||||||
<ClCompile Include="src\fiber_redis_pipeline.cpp" />
|
<ClCompile Include="src\fiber_redis_pipeline.cpp" />
|
||||||
<ClCompile Include="src\fiber_sem.cpp" />
|
<ClCompile Include="src\fiber_sem.cpp" />
|
||||||
<ClCompile Include="src\fiber_server.cpp" />
|
<ClCompile Include="src\fiber_server.cpp" />
|
||||||
|
@ -36,6 +36,12 @@
|
|||||||
<ClCompile Include="src\fiber_lock.cpp">
|
<ClCompile Include="src\fiber_lock.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\fiber_mutex.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\fiber_mutex_stat.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="src\fiber_redis_pipeline.cpp">
|
<ClCompile Include="src\fiber_redis_pipeline.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -74,6 +80,12 @@
|
|||||||
<ClInclude Include="include\fiber\fiber_lock.hpp">
|
<ClInclude Include="include\fiber\fiber_lock.hpp">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\fiber\fiber_mutex.hpp">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\fiber\fiber_mutex_stat.hpp">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="include\fiber\fiber_redis_pipeline.hpp">
|
<ClInclude Include="include\fiber\fiber_redis_pipeline.hpp">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -316,6 +316,7 @@
|
|||||||
<ClInclude Include="include\fiber\fiber_event.hpp" />
|
<ClInclude Include="include\fiber\fiber_event.hpp" />
|
||||||
<ClInclude Include="include\fiber\fiber_lock.hpp" />
|
<ClInclude Include="include\fiber\fiber_lock.hpp" />
|
||||||
<ClInclude Include="include\fiber\fiber_mutex.hpp" />
|
<ClInclude Include="include\fiber\fiber_mutex.hpp" />
|
||||||
|
<ClInclude Include="include\fiber\fiber_mutex_stat.hpp" />
|
||||||
<ClInclude Include="include\fiber\fiber_redis_pipeline.hpp" />
|
<ClInclude Include="include\fiber\fiber_redis_pipeline.hpp" />
|
||||||
<ClInclude Include="include\fiber\fiber_sem.hpp" />
|
<ClInclude Include="include\fiber\fiber_sem.hpp" />
|
||||||
<ClInclude Include="include\fiber\fiber_tbox.hpp" />
|
<ClInclude Include="include\fiber\fiber_tbox.hpp" />
|
||||||
@ -345,6 +346,7 @@
|
|||||||
<ClCompile Include="src\fiber_event.cpp" />
|
<ClCompile Include="src\fiber_event.cpp" />
|
||||||
<ClCompile Include="src\fiber_lock.cpp" />
|
<ClCompile Include="src\fiber_lock.cpp" />
|
||||||
<ClCompile Include="src\fiber_mutex.cpp" />
|
<ClCompile Include="src\fiber_mutex.cpp" />
|
||||||
|
<ClCompile Include="src\fiber_mutex_stat.cpp" />
|
||||||
<ClCompile Include="src\fiber_redis_pipeline.cpp" />
|
<ClCompile Include="src\fiber_redis_pipeline.cpp" />
|
||||||
<ClCompile Include="src\fiber_sem.cpp" />
|
<ClCompile Include="src\fiber_sem.cpp" />
|
||||||
<ClCompile Include="src\fiber_server.cpp" />
|
<ClCompile Include="src\fiber_server.cpp" />
|
||||||
|
@ -75,6 +75,9 @@
|
|||||||
<ClCompile Include="src\fiber_mutex.cpp">
|
<ClCompile Include="src\fiber_mutex.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\fiber_mutex_stat.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="src\tcp_keeper.cpp">
|
<ClCompile Include="src\tcp_keeper.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -140,6 +143,9 @@
|
|||||||
<ClInclude Include="include\fiber\fiber_mutex.hpp">
|
<ClInclude Include="include\fiber\fiber_mutex.hpp">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\fiber\fiber_mutex_stat.hpp">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="include\fiber\http_server.hpp">
|
<ClInclude Include="include\fiber\http_server.hpp">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -4,7 +4,17 @@
|
|||||||
|
|
||||||
namespace acl {
|
namespace acl {
|
||||||
|
|
||||||
fiber::fiber(bool running /* = false */)
|
fiber::fiber(void)
|
||||||
|
{
|
||||||
|
f_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fiber::fiber(ACL_FIBER *f)
|
||||||
|
{
|
||||||
|
f_ = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
fiber::fiber(bool running)
|
||||||
{
|
{
|
||||||
if (running) {
|
if (running) {
|
||||||
f_ = acl_fiber_running();
|
f_ = acl_fiber_running();
|
||||||
@ -31,6 +41,12 @@ unsigned int fiber::self(void)
|
|||||||
return acl_fiber_self();
|
return acl_fiber_self();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int fiber::id(const fiber& fb)
|
||||||
|
{
|
||||||
|
ACL_FIBER *f = fb.get_fiber();
|
||||||
|
return f ? acl_fiber_id(f) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
int fiber::get_errno(void) const
|
int fiber::get_errno(void) const
|
||||||
{
|
{
|
||||||
return f_ ? acl_fiber_errno(f_) : -1;
|
return f_ ? acl_fiber_errno(f_) : -1;
|
||||||
|
@ -1,16 +1,24 @@
|
|||||||
#include "stdafx.hpp"
|
#include "stdafx.hpp"
|
||||||
|
#include "fiber/fiber.hpp"
|
||||||
#include "fiber/fiber_mutex.hpp"
|
#include "fiber/fiber_mutex.hpp"
|
||||||
|
|
||||||
namespace acl {
|
namespace acl {
|
||||||
|
|
||||||
fiber_mutex::fiber_mutex(void)
|
fiber_mutex::fiber_mutex(ACL_FIBER_MUTEX *mutex /* NULL */)
|
||||||
{
|
{
|
||||||
mutex_ = acl_fiber_mutex_create(0);
|
if (mutex) {
|
||||||
|
mutex_ = mutex;
|
||||||
|
mutex_internal_ = NULL;
|
||||||
|
} else {
|
||||||
|
mutex_internal_ = mutex_ = acl_fiber_mutex_create(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fiber_mutex::~fiber_mutex(void)
|
fiber_mutex::~fiber_mutex(void)
|
||||||
{
|
{
|
||||||
acl_fiber_mutex_free(mutex_);
|
if (mutex_internal_) {
|
||||||
|
acl_fiber_mutex_free(mutex_internal_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fiber_mutex::lock(void)
|
bool fiber_mutex::lock(void)
|
||||||
@ -30,4 +38,29 @@ bool fiber_mutex::unlock(void)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fiber_mutex::deadlock(fiber_mutex_stats& out)
|
||||||
|
{
|
||||||
|
ACL_FIBER_MUTEX_STATS *stats = acl_fiber_mutex_deadlock();
|
||||||
|
|
||||||
|
if (stats == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < stats->count; i++) {
|
||||||
|
fiber_mutex_stat stat;
|
||||||
|
stat.fb = new fiber(stats->stats[i].fiber);
|
||||||
|
stat.waiting = stats->stats[i].waiting;
|
||||||
|
|
||||||
|
for (size_t j = 0; j < stats->stats[i].count; j++) {
|
||||||
|
ACL_FIBER_MUTEX* mutex = stats->stats[i].holding[j];
|
||||||
|
stat.holding.push_back(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
out.stats.push_back(stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
acl_fiber_mutex_stats_free(stats);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace acl
|
} // namespace acl
|
||||||
|
16
lib_fiber/cpp/src/fiber_mutex_stat.cpp
Normal file
16
lib_fiber/cpp/src/fiber_mutex_stat.cpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#include "stdafx.hpp"
|
||||||
|
#include "fiber/fiber.hpp"
|
||||||
|
#include "fiber/fiber_mutex.hpp"
|
||||||
|
#include "fiber/fiber_mutex_stat.hpp"
|
||||||
|
|
||||||
|
namespace acl {
|
||||||
|
|
||||||
|
fiber_mutex_stats::~fiber_mutex_stats(void)
|
||||||
|
{
|
||||||
|
for (std::vector<fiber_mutex_stat>::iterator it = stats.begin();
|
||||||
|
it != stats.end(); ++it) {
|
||||||
|
delete (*it).fb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace acl
|
@ -65,7 +65,7 @@ static void fiber_check(ACL_FIBER *fb, void *ctx)
|
|||||||
sleep(1);
|
sleep(1);
|
||||||
printf("\r\n");
|
printf("\r\n");
|
||||||
//acl_fiber_mutex_profile();
|
//acl_fiber_mutex_profile();
|
||||||
stats = acl_fiber_mutex_deadcheck();
|
stats = acl_fiber_mutex_deadlock();
|
||||||
if (stats) {
|
if (stats) {
|
||||||
acl_fiber_mutex_stats_show(stats);
|
acl_fiber_mutex_stats_show(stats);
|
||||||
acl_fiber_mutex_stats_free(stats);
|
acl_fiber_mutex_stats_free(stats);
|
||||||
|
6
lib_fiber/samples/dead_lock2/Makefile
Normal file
6
lib_fiber/samples/dead_lock2/Makefile
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Don't build the sample on MacOS because libunwind don't support it.
|
||||||
|
include ./Makefile.in
|
||||||
|
ifeq ($(findstring Linux, $(UNIXNAME)), Linux)
|
||||||
|
SYSLIB += -lunwind -lunwind-x86_64
|
||||||
|
endif
|
||||||
|
PROG = dead_lock
|
174
lib_fiber/samples/dead_lock2/Makefile.in
Normal file
174
lib_fiber/samples/dead_lock2/Makefile.in
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
CC = g++
|
||||||
|
|
||||||
|
CFLAGS = -c -g -W -Wall -Wcast-qual -Wcast-align \
|
||||||
|
-Wno-long-long -Wpointer-arith -Werror -Wshadow -O0 \
|
||||||
|
-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -D_USE_FAST_MACRO
|
||||||
|
|
||||||
|
###########################################################
|
||||||
|
#Check system:
|
||||||
|
# Linux, SunOS, Solaris, BSD variants, AIX, HP-UX
|
||||||
|
SYSLIB = -ldl -lpthread -lz
|
||||||
|
CHECKSYSRES = @echo "Unknow system type!";exit 1
|
||||||
|
UNIXNAME = $(shell uname -sm)
|
||||||
|
OSTYPE = $(shell uname -p)
|
||||||
|
RPATH = linux64
|
||||||
|
|
||||||
|
ifeq ($(CC),)
|
||||||
|
CC = g++
|
||||||
|
endif
|
||||||
|
|
||||||
|
OS_ENV=$(shell uname -a)
|
||||||
|
ifeq ($(findstring WSL, $(OS_ENV)), WSL)
|
||||||
|
SYSLIB += -liconv
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(findstring ubuntu, $(OS_ENV)), ubuntu)
|
||||||
|
SYSLIB += -liconv
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(findstring Alpine, $(shell uname -a)), Alpine)
|
||||||
|
SYSLIB += -lucontext
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(findstring g++, $(CC)), g++)
|
||||||
|
GCC_VERSION:=$(shell echo `gcc --version|grep ^gcc|cut -d' ' -f3`)
|
||||||
|
GCC_MAJOR:=$(shell echo "$(GCC_VERSION)" | cut -d'.' -f1)
|
||||||
|
GCC_MINOR:=$(shell echo "$(GCC_VERSION)" | cut -d'.' -f2)
|
||||||
|
GCC_VER:=$(shell [ $(GCC_MAJOR) -gt 4 -o \( $(GCC_MAJOR) -eq 4 -a $(GCC_MINOR) -ge 7 \) ] && echo true)
|
||||||
|
ifeq ($(GCC_VER), true)
|
||||||
|
CFLAGS += -std=c++11 -DACL_USE_CPP11
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# For FreeBSD
|
||||||
|
ifeq ($(findstring FreeBSD, $(UNIXNAME)), FreeBSD)
|
||||||
|
ifeq ($(findstring gcc, $(CC)), gcc)
|
||||||
|
CFLAGS += -Wstrict-prototypes
|
||||||
|
endif
|
||||||
|
CFLAGS += -DFREEBSD -D_REENTRANT
|
||||||
|
SYSLIB = -lcrypt -lpthread -lz
|
||||||
|
RPATH = freebsd
|
||||||
|
endif
|
||||||
|
|
||||||
|
# For Darwin
|
||||||
|
ifeq ($(findstring Darwin, $(UNIXNAME)), Darwin)
|
||||||
|
# CC += -arch x86_64 -arch arm64
|
||||||
|
CFLAGS += -DMACOSX -Wno-invalid-source-encoding \
|
||||||
|
-Wno-invalid-offsetof
|
||||||
|
UNIXTYPE = MACOSX
|
||||||
|
SYSLIB += -liconv -rdynamic
|
||||||
|
RPATH = macos
|
||||||
|
endif
|
||||||
|
|
||||||
|
#Path for Linux
|
||||||
|
ifeq ($(findstring Linux, $(UNIXNAME)), Linux)
|
||||||
|
ifeq ($CC, "gcc")
|
||||||
|
CFLAGS += -Wstrict-prototypes
|
||||||
|
endif
|
||||||
|
ifeq ($(findstring i686, $(OSTYPE)), i686)
|
||||||
|
RPATH = linux32
|
||||||
|
endif
|
||||||
|
ifeq ($(findstring x86_64, $(OSTYPE)), x86_64)
|
||||||
|
RPATH = linux64
|
||||||
|
endif
|
||||||
|
ifeq ($(HAS_IO_URING), yes)
|
||||||
|
SYSLIB += -luring
|
||||||
|
endif
|
||||||
|
ifeq ($(has_io_uring), yes)
|
||||||
|
SYSLIB += -luring
|
||||||
|
endif
|
||||||
|
# CFLAGS += -DLINUX2 -D_REENTRANT
|
||||||
|
CFLAGS += -D_REENTRANT
|
||||||
|
SYSLIB += -lcrypt
|
||||||
|
endif
|
||||||
|
|
||||||
|
#Path for SunOS
|
||||||
|
ifeq ($(findstring SunOS, $(UNIXNAME)), SunOS)
|
||||||
|
ifeq ($(findstring 86, $(UNIXNAME)), 86)
|
||||||
|
SYSLIB += -lsocket -lnsl -lrt
|
||||||
|
endif
|
||||||
|
ifeq ($(findstring sun4u, $(UNIXNAME)), sun4u)
|
||||||
|
SYSLIB += -lsocket -lnsl -lrt
|
||||||
|
endif
|
||||||
|
ifeq ($CC, "gcc")
|
||||||
|
CFLAGS += -Wstrict-prototypes
|
||||||
|
endif
|
||||||
|
CFLAGS += -DSUNOS5 -D_REENTRANT
|
||||||
|
RPATH = sunos_x86
|
||||||
|
endif
|
||||||
|
|
||||||
|
#Path for HP-UX
|
||||||
|
ifeq ($(findstring HP-UX, $(UNIXNAME)), HP-UX)
|
||||||
|
ifeq ($CC, "gcc")
|
||||||
|
CFLAGS += -Wstrict-prototypes
|
||||||
|
endif
|
||||||
|
CFLAGS += -DHP_UX -DHPUX11
|
||||||
|
PLAT_NAME=hp-ux
|
||||||
|
endif
|
||||||
|
|
||||||
|
# For CYGWIN
|
||||||
|
ifeq ($(findstring CYGWIN, $(UNIXNAME)), CYGWIN)
|
||||||
|
SYSLIB = -lpthread -rdynamic
|
||||||
|
CFLAGS += -DLINUX2 -DMINGW
|
||||||
|
UNIXTYPE = LINUX
|
||||||
|
endif
|
||||||
|
|
||||||
|
# For MINGW
|
||||||
|
ifeq ($(findstring MINGW, $(UNIXNAME)), MINGW)
|
||||||
|
SYSLIB = -lpthread -rdynamic
|
||||||
|
CFLAGS += -DLINUX2 -DMINGW
|
||||||
|
UNIXTYPE = LINUX
|
||||||
|
endif
|
||||||
|
|
||||||
|
# For MSYS
|
||||||
|
ifeq ($(findstring MSYS, $(UNIXNAME)), MSYS)
|
||||||
|
SYSLIB = -lpthread -rdynamic
|
||||||
|
CFLAGS += -DLINUX2 -DMINGW
|
||||||
|
UNIXTYPE = LINUX
|
||||||
|
endif
|
||||||
|
|
||||||
|
#Find system type.
|
||||||
|
ifneq ($(SYSPATH),)
|
||||||
|
CHECKSYSRES = @echo "System is $(shell uname -sm)"
|
||||||
|
endif
|
||||||
|
###########################################################
|
||||||
|
|
||||||
|
CFLAGS += -I.. -I../../../lib_acl/include -I../../../lib_protocol/include -I../../../lib_acl_cpp/include \
|
||||||
|
-I../../../lib_fiber/c/include -I../../../lib_fiber/cpp/include
|
||||||
|
EXTLIBS =
|
||||||
|
LDFLAGS = -L../../../lib_fiber/lib -lfiber_cpp \
|
||||||
|
-L../../../lib_acl_cpp/lib -lacl_cpp \
|
||||||
|
-L../../../lib_protocol/lib -lprotocol \
|
||||||
|
-L../../../lib_acl/lib -lacl \
|
||||||
|
-lfiber $(EXTLIBS) $(SYSLIB)
|
||||||
|
|
||||||
|
COMPILE = $(CC) $(CFLAGS)
|
||||||
|
LINK = $(CC) $(OBJ) $(LDFLAGS)
|
||||||
|
###########################################################
|
||||||
|
OBJ_PATH = .
|
||||||
|
|
||||||
|
#Project's objs
|
||||||
|
SRC = $(wildcard *.cpp)
|
||||||
|
OBJ = $(patsubst %.cpp, $(OBJ_PATH)/%.o, $(notdir $(SRC)))
|
||||||
|
|
||||||
|
$(OBJ_PATH)/%.o: %.cpp
|
||||||
|
$(COMPILE) $< -o $@
|
||||||
|
|
||||||
|
.PHONY = all clean
|
||||||
|
all: RM $(OBJ)
|
||||||
|
$(LINK) -o $(PROG)
|
||||||
|
@echo ""
|
||||||
|
@echo "All ok! Output:$(PROG)"
|
||||||
|
@echo ""
|
||||||
|
RM:
|
||||||
|
rm -f $(PROG)
|
||||||
|
clean cl:
|
||||||
|
rm -f $(PROG)
|
||||||
|
rm -f $(OBJ)
|
||||||
|
|
||||||
|
rebuild rb: clean all
|
||||||
|
|
||||||
|
install:
|
||||||
|
cp $(PROG) ../../../dist/master/libexec/$(RPATH)/
|
||||||
|
cp $(PROG).cf ../../../dist/master/conf/service/
|
||||||
|
###########################################################
|
152
lib_fiber/samples/dead_lock2/main.cpp
Normal file
152
lib_fiber/samples/dead_lock2/main.cpp
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "fiber/libfiber.h"
|
||||||
|
#include "fiber/libfiber.hpp"
|
||||||
|
|
||||||
|
class myfiber : public acl::fiber {
|
||||||
|
public:
|
||||||
|
myfiber(std::vector<acl::fiber_mutex*>& locks) : locks_(locks) {}
|
||||||
|
~myfiber(void) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<acl::fiber_mutex*>& locks_;
|
||||||
|
|
||||||
|
// @override
|
||||||
|
void run(void) {
|
||||||
|
size_t i = acl::fiber::self() % locks_.size();
|
||||||
|
acl::fiber_mutex* lock = locks_[i];
|
||||||
|
|
||||||
|
printf("fiber-%d wait, locks[%zd]=%p\r\n",
|
||||||
|
acl::fiber::self(), i, lock);
|
||||||
|
lock->lock();
|
||||||
|
printf("fiber-%d locked, locks[%ld]=%p\r\n",
|
||||||
|
acl::fiber::self(), i, lock);
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
i = (acl::fiber::self() + 1) % locks_.size();
|
||||||
|
lock = locks_[i];
|
||||||
|
|
||||||
|
printf("fiber-%d wait,locks[%zd]=%p\r\n",
|
||||||
|
acl::fiber::self(), i, lock);
|
||||||
|
lock->lock();
|
||||||
|
printf("fiber-%d locked, locks[%zd]=%p\r\n",
|
||||||
|
acl::fiber::self(), i, lock);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class fiber_check : public acl::fiber {
|
||||||
|
public:
|
||||||
|
fiber_check(void) {}
|
||||||
|
~fiber_check(void) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// @override
|
||||||
|
void run(void) {
|
||||||
|
while (true) {
|
||||||
|
sleep(2);
|
||||||
|
printf("\r\n");
|
||||||
|
acl::fiber_mutex_stats stats;
|
||||||
|
if (acl::fiber_mutex::deadlock(stats)) {
|
||||||
|
printf("Deadlock happened!\r\n\r\n");
|
||||||
|
show(stats);
|
||||||
|
} else {
|
||||||
|
printf("No deadlock happened!\r\n");
|
||||||
|
}
|
||||||
|
printf("=======================================\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void show(const acl::fiber_mutex_stats& stats) {
|
||||||
|
for (std::vector<acl::fiber_mutex_stat>::const_iterator
|
||||||
|
cit = stats.stats.begin(); cit != stats.stats.end();
|
||||||
|
++cit) {
|
||||||
|
show(*cit);
|
||||||
|
printf("\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void show(const acl::fiber_mutex_stat& stat) {
|
||||||
|
printf("fiber-%d:\r\n", acl::fiber::id(*stat.fb));
|
||||||
|
|
||||||
|
std::vector<acl::fiber_frame> stack;
|
||||||
|
acl::fiber::stacktrace(*stat.fb, stack, 50);
|
||||||
|
show_stack(stack);
|
||||||
|
|
||||||
|
for (std::vector<ACL_FIBER_MUTEX*>::const_iterator
|
||||||
|
cit = stat.holding.begin();
|
||||||
|
cit != stat.holding.end(); ++cit) {
|
||||||
|
printf("Holding mutex=%p\r\n", *cit);
|
||||||
|
}
|
||||||
|
printf("Waiting for mutex=%p\r\n", stat.waiting);
|
||||||
|
}
|
||||||
|
|
||||||
|
void show_stack(const std::vector<acl::fiber_frame>& stack)
|
||||||
|
{
|
||||||
|
for (std::vector<acl::fiber_frame>::const_iterator
|
||||||
|
cit = stack.begin(); cit != stack.end(); ++cit) {
|
||||||
|
printf("0x%lx(%s)+0x%lx\r\n",
|
||||||
|
(*cit).pc, (*cit).func.c_str(), (*cit).off);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void usage(const char *procname)
|
||||||
|
{
|
||||||
|
printf("usage: %s -h [help] -c fibers_count -n locks_count\r\n", procname);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i, ch, nlocks = 2, nfibers = 2;
|
||||||
|
std::vector<acl::fiber_mutex*> locks;
|
||||||
|
|
||||||
|
while ((ch = getopt(argc, argv, "hc:n:")) > 0) {
|
||||||
|
switch (ch) {
|
||||||
|
case 'h':
|
||||||
|
usage(argv[0]);
|
||||||
|
return 0;
|
||||||
|
case 'c':
|
||||||
|
nfibers = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
nlocks = atoi(optarg);
|
||||||
|
if (nlocks <= 0) {
|
||||||
|
nlocks = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < nlocks; i++) {
|
||||||
|
acl::fiber_mutex* lock = new acl::fiber_mutex;
|
||||||
|
locks.push_back(lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<acl::fiber*> fibers;
|
||||||
|
|
||||||
|
for (i = 0; i < nfibers; i++) {
|
||||||
|
acl::fiber* fb = new myfiber(locks);
|
||||||
|
fibers.push_back(fb);
|
||||||
|
fb->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
fiber_check check;
|
||||||
|
check.start();
|
||||||
|
|
||||||
|
acl::fiber::schedule();
|
||||||
|
|
||||||
|
for (std::vector<acl::fiber_mutex*>::iterator it = locks.begin();
|
||||||
|
it != locks.end(); ++it) {
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::vector<acl::fiber*>::iterator it = fibers.begin();
|
||||||
|
it != fibers.end(); ++it) {
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
@ -50,14 +50,12 @@ private:
|
|||||||
|
|
||||||
void run(void)
|
void run(void)
|
||||||
{
|
{
|
||||||
std::vector<acl::fiber_frame> stack;
|
|
||||||
|
|
||||||
for (int i = 0; i < count_; i++) {
|
for (int i = 0; i < count_; i++) {
|
||||||
|
std::vector<acl::fiber_frame> stack;
|
||||||
acl::fiber::stacktrace(*fb_, stack, 50);
|
acl::fiber::stacktrace(*fb_, stack, 50);
|
||||||
show_stack(stack);
|
show_stack(stack);
|
||||||
printf("\r\n");
|
printf("\r\n");
|
||||||
|
|
||||||
stack.clear();
|
|
||||||
sleep(2);
|
sleep(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user