从skynet-1.4.0中分离出来的timer实现代码。
Last active
June 10, 2021 06:54
-
-
Save losophy/f12f340a3a016b4385ccb30a31d7b989 to your computer and use it in GitHub Desktop.
skynet-1.4.0 timer实现代码
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static void * | |
thread_timer(void *p) { | |
struct monitor * m = p; | |
skynet_initthread(THREAD_TIMER); | |
for (;;) { | |
skynet_updatetime(); | |
skynet_socket_updatetime(); | |
CHECK_ABORT | |
wakeup(m,m->count-1); // 贪婪唤醒工作线程 | |
usleep(2500); // 睡眠 2.5 ms | |
if (SIG) { | |
signal_hup(); | |
SIG = 0; | |
} | |
} | |
// wakeup socket thread | |
skynet_socket_exit(); | |
// wakeup all worker thread | |
pthread_mutex_lock(&m->mutex); | |
m->quit = 1; | |
pthread_cond_broadcast(&m->cond); | |
pthread_mutex_unlock(&m->mutex); | |
return NULL; | |
} | |
static void | |
add_node(struct timer *T,struct timer_node *node) { | |
uint32_t time=node->expire; | |
uint32_t current_time=T->time; | |
// 这里我替换了 宏定义,方便阅读代码 | |
if ((time|255)==(current_time|255)) { | |
link(&T->near[time&255],node); | |
} else { | |
int i; | |
uint32_t mask=256 << 6; | |
for (i=0;i<3;i++) { | |
if ((time|(mask-1))==(current_time|(mask-1))) { | |
break; | |
} | |
mask <<= TIME_L6EVEL_SHIFT; | |
} | |
int index = (time >> (8 + i*6)) & 63; | |
link(&T->t[i][index], node); | |
} | |
} | |
static void | |
timer_add(struct timer *T,void *arg,size_t sz,int time) { | |
struct timer_node *node = (struct timer_node *)skynet_malloc(sizeof(*node)+sz); | |
memcpy(node+1,arg,sz); | |
SPIN_LOCK(T); | |
// assert(time<=0xFC000000); //超时tick不能超过 0xFC000000 | |
node->expire=time+T->time; | |
add_node(T,node); | |
SPIN_UNLOCK(T); | |
} | |
static inline void | |
timer_execute(struct timer *T) { | |
int idx = T->time & TIME_NEAR_MASK; | |
while (T->near[idx].head.next) { | |
struct timer_node *current = link_clear(&T->near[idx]); | |
SPIN_UNLOCK(T); | |
// dispatch_list don't need lock T | |
dispatch_list(current); | |
SPIN_LOCK(T); | |
} | |
} | |
static void | |
timer_update(struct timer *T) { | |
SPIN_LOCK(T); | |
// try to dispatch timeout 0 (rare condition) | |
timer_execute(T); | |
// shift time first, and then dispatch timer message | |
timer_shift(T); | |
timer_execute(T); | |
SPIN_UNLOCK(T); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct timer { | |
struct link_list near[TIME_NEAR];//// 工作轮盘 | |
struct link_list t[4][TIME_LEVEL];// 发散轮盘 | |
struct spinlock lock; | |
uint32_t time;//表示时间轮转动次数,当时间轮走完一整个轮回后,该字段会重置为 0,继续轮回; | |
uint32_t starttime;//表示定时器初始化时的时间戳(单位为秒),该时间戳获取后将不会变化; | |
uint64_t current;//表示从 starttime 开始,经过了多少厘秒(1/100 秒),只增不减; | |
uint64_t current_point;//表示以厘秒为单位的本机当前时间戳,可增(本机时间往前调)可减(本机时间往回调); | |
}; | |
// 定时事件 | |
struct timer_event { | |
uint32_t handle; // 注册该事件的服务 handle id | |
int session; // 该定时消息的 session | |
}; | |
// 事件节点,插入到定时列表中 | |
struct timer_node { | |
struct timer_node *next; | |
uint32_t expire; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment