Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
阿啄debugIT
libfastcommon
提交
93e6cec0
L
libfastcommon
项目概览
阿啄debugIT
/
libfastcommon
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
libfastcommon
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
93e6cec0
编写于
11月 29, 2020
作者:
Y
YuQing
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
locked_timer: atomic opt for lock_index
上级
b236808a
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
55 addition
and
24 deletion
+55
-24
HISTORY
HISTORY
+1
-1
src/locked_timer.c
src/locked_timer.c
+45
-20
src/locked_timer.h
src/locked_timer.h
+9
-3
未找到文件。
HISTORY
浏览文件 @
93e6cec0
Version 1.44 2020-11-2
6
Version 1.44 2020-11-2
9
* add test file src/tests/test_pthread_lock.c
* add uniq_skiplist.[hc]
* add function split_string_ex
...
...
src/locked_timer.c
浏览文件 @
93e6cec0
...
...
@@ -64,8 +64,9 @@ static int locked_timer_init_slots(LockedTimer *timer)
return
0
;
}
int
locked_timer_init
(
LockedTimer
*
timer
,
const
int
slot_count
,
const
int64_t
current_time
,
const
int
shared_lock_count
)
int
locked_timer_init_ex
(
LockedTimer
*
timer
,
const
int
slot_count
,
const
int64_t
current_time
,
const
int
shared_lock_count
,
const
bool
set_lock_index
)
{
if
(
slot_count
<=
0
||
current_time
<=
0
)
{
return
EINVAL
;
...
...
@@ -73,6 +74,7 @@ int locked_timer_init(LockedTimer *timer, const int slot_count,
timer
->
slot_count
=
slot_count
;
timer
->
entry_shares
.
count
=
shared_lock_count
;
timer
->
entry_shares
.
set_lock_index
=
set_lock_index
;
timer
->
base_time
=
current_time
;
//base time for slot 0
timer
->
current_time
=
current_time
;
return
locked_timer_init_slots
(
timer
);
...
...
@@ -111,30 +113,50 @@ void locked_timer_destroy(LockedTimer *timer)
#define TIMER_GET_SLOT_POINTER(timer, expires) \
(timer->slots + TIMER_GET_SLOT_INDEX(timer, expires))
#define TIMER_ENTRY_LOCK(timer,
entry
) \
PTHREAD_MUTEX_LOCK(timer->entry_shares.locks +
entry->
lock_index)
#define TIMER_ENTRY_LOCK(timer,
lock_index
) \
PTHREAD_MUTEX_LOCK(timer->entry_shares.locks + lock_index)
#define TIMER_ENTRY_UNLOCK(timer,
entry
) \
PTHREAD_MUTEX_UNLOCK(timer->entry_shares.locks +
entry->
lock_index)
#define TIMER_ENTRY_UNLOCK(timer,
lock_index
) \
PTHREAD_MUTEX_UNLOCK(timer->entry_shares.locks + lock_index)
#define TIMER_ENTRY_FETCH_LOCK_INDEX(timer, entry) \
(timer->entry_shares.set_lock_index ? \
__sync_add_and_fetch(&entry->lock_index, 0) : entry->lock_index)
#define TIMER_SET_ENTRY_STATUS_AND_SINDEX(timer, slot, entry) \
#define TIMER_ENTRY_FETCH_AND_LOCK(timer, entry) \
lock_index = TIMER_ENTRY_FETCH_LOCK_INDEX(timer, entry); \
PTHREAD_MUTEX_LOCK(timer->entry_shares.locks + lock_index)
#define TIMER_SET_ENTRY_STATUS_AND_SINDEX(timer, slot, entry, lock_index) \
do { \
TIMER_ENTRY_LOCK(timer,
entry);
\
TIMER_ENTRY_LOCK(timer,
lock_index);
\
entry->status = FAST_TIMER_STATUS_NORMAL; \
entry->slot_index = slot - timer->slots; \
TIMER_ENTRY_UNLOCK(timer,
entry);
\
TIMER_ENTRY_UNLOCK(timer,
lock_index);
\
} while (0)
static
inline
void
add_entry
(
LockedTimer
*
timer
,
LockedTimerSlot
*
slot
,
LockedTimerEntry
*
entry
,
const
int64_t
expires
,
const
int
flags
)
{
int
lock_index
;
if
((
flags
&
FAST_TIMER_FLAGS_SET_ENTRY_LOCK
)
!=
0
)
{
if
(
timer
->
entry_shares
.
set_lock_index
)
{
int
old_index
;
/* init the entry on the first call */
entry
->
lock_index
=
((
unsigned
long
)
entry
)
%
timer
->
entry_shares
.
count
;
lock_index
=
((
unsigned
long
)
entry
)
%
timer
->
entry_shares
.
count
;
old_index
=
entry
->
lock_index
;
while
(
!
__sync_bool_compare_and_swap
(
&
entry
->
lock_index
,
old_index
,
lock_index
))
{
old_index
=
__sync_add_and_fetch
(
&
entry
->
lock_index
,
0
);
}
}
else
{
lock_index
=
entry
->
lock_index
;
}
TIMER_SET_ENTRY_STATUS_AND_SINDEX
(
timer
,
slot
,
entry
);
TIMER_SET_ENTRY_STATUS_AND_SINDEX
(
timer
,
slot
,
entry
,
lock_index
);
}
else
{
lock_index
=
TIMER_ENTRY_FETCH_LOCK_INDEX
(
timer
,
entry
);
}
PTHREAD_MUTEX_LOCK
(
&
slot
->
lock
);
...
...
@@ -146,7 +168,7 @@ static inline void add_entry(LockedTimer *timer, LockedTimerSlot *slot,
if
((
flags
&
FAST_TIMER_FLAGS_SET_ENTRY_LOCK
)
==
0
)
{
/* MUST set entry status and slot index in the end when entry move */
TIMER_SET_ENTRY_STATUS_AND_SINDEX
(
timer
,
slot
,
entry
);
TIMER_SET_ENTRY_STATUS_AND_SINDEX
(
timer
,
slot
,
entry
,
lock_index
);
}
PTHREAD_MUTEX_UNLOCK
(
&
slot
->
lock
);
}
...
...
@@ -159,9 +181,11 @@ static inline int check_set_entry_status(LockedTimer *timer,
LockedTimerEntry
*
entry
,
int
*
slot_index
,
const
int
new_status
)
{
int
result
;
int
lock_index
;
lock_index
=
TIMER_ENTRY_FETCH_LOCK_INDEX
(
timer
,
entry
);
while
(
1
)
{
TIMER_ENTRY_LOCK
(
timer
,
entry
);
TIMER_ENTRY_LOCK
(
timer
,
lock_index
);
switch
(
entry
->
status
)
{
case
FAST_TIMER_STATUS_CLEARED
:
result
=
ECANCELED
;
...
...
@@ -183,7 +207,7 @@ static inline int check_set_entry_status(LockedTimer *timer,
break
;
}
*
slot_index
=
entry
->
slot_index
;
TIMER_ENTRY_UNLOCK
(
timer
,
entry
);
TIMER_ENTRY_UNLOCK
(
timer
,
lock_index
);
if
(
result
!=
EAGAIN
)
{
return
result
;
...
...
@@ -266,6 +290,7 @@ int locked_timer_timeouts_get(LockedTimer *timer, const int64_t current_time,
LockedTimerEntry
*
tmp
;
LockedTimerEntry
*
tail
;
bool
is_valid
;
int
lock_index
;
int
count
;
if
(
timer
->
current_time
>=
current_time
)
{
...
...
@@ -283,14 +308,14 @@ int locked_timer_timeouts_get(LockedTimer *timer, const int64_t current_time,
if
(
entry
->
rehash
)
{
new_slot
=
TIMER_GET_SLOT_POINTER
(
timer
,
entry
->
expires
);
if
(
new_slot
!=
slot
)
{
//check to avoid deadlock
TIMER_ENTRY_LOCK
(
timer
,
entry
);
TIMER_ENTRY_
FETCH_AND_
LOCK
(
timer
,
entry
);
if
(
entry
->
status
==
FAST_TIMER_STATUS_NORMAL
)
{
entry
->
status
=
FAST_TIMER_STATUS_MOVING
;
is_valid
=
true
;
}
else
{
is_valid
=
false
;
}
TIMER_ENTRY_UNLOCK
(
timer
,
entry
);
TIMER_ENTRY_UNLOCK
(
timer
,
lock_index
);
if
(
is_valid
)
{
fc_list_del_init
(
&
entry
->
dlink
);
...
...
@@ -302,14 +327,14 @@ int locked_timer_timeouts_get(LockedTimer *timer, const int64_t current_time,
}
}
}
else
{
//expired
TIMER_ENTRY_LOCK
(
timer
,
entry
);
TIMER_ENTRY_
FETCH_AND_
LOCK
(
timer
,
entry
);
if
(
entry
->
status
==
FAST_TIMER_STATUS_NORMAL
)
{
entry
->
status
=
FAST_TIMER_STATUS_TIMEOUT
;
is_valid
=
true
;
}
else
{
is_valid
=
false
;
}
TIMER_ENTRY_UNLOCK
(
timer
,
entry
);
TIMER_ENTRY_UNLOCK
(
timer
,
lock_index
);
if
(
is_valid
)
{
fc_list_del_init
(
&
entry
->
dlink
);
...
...
src/locked_timer.h
浏览文件 @
93e6cec0
...
...
@@ -38,7 +38,7 @@ typedef struct locked_timer_entry {
struct
fc_list_head
dlink
;
//for timer slot
struct
locked_timer_entry
*
next
;
//for timeout chain
uint32_t
slot_index
;
//for slot lock
uint16_t
lock_index
;
//for entry lock
volatile
uint16_t
lock_index
;
//for entry lock
uint8_t
status
;
bool
rehash
;
}
LockedTimerEntry
;
...
...
@@ -49,6 +49,7 @@ typedef struct locked_timer_slot {
}
LockedTimerSlot
;
typedef
struct
locked_timer_shared_locks
{
bool
set_lock_index
;
uint16_t
count
;
pthread_mutex_t
*
locks
;
}
LockedTimerSharedLocks
;
...
...
@@ -65,6 +66,10 @@ typedef struct locked_timer {
extern
"C"
{
#endif
#define locked_timer_init(timer, slot_count, current_time, shared_lock_count) \
locked_timer_init_ex(timer, slot_count, current_time, shared_lock_count, \
true)
#define locked_timer_add(timer, entry) \
locked_timer_add_ex(timer, entry, (entry)->expires, \
FAST_TIMER_FLAGS_SET_ENTRY_LOCK)
...
...
@@ -72,8 +77,9 @@ extern "C" {
#define locked_timer_remove(timer, entry) \
locked_timer_remove_ex(timer, entry, FAST_TIMER_STATUS_CLEARED)
int
locked_timer_init
(
LockedTimer
*
timer
,
const
int
slot_count
,
const
int64_t
current_time
,
const
int
shared_lock_count
);
int
locked_timer_init_ex
(
LockedTimer
*
timer
,
const
int
slot_count
,
const
int64_t
current_time
,
const
int
shared_lock_count
,
const
bool
set_lock_index
);
void
locked_timer_destroy
(
LockedTimer
*
timer
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录