Skip to content

Instantly share code, notes, and snippets.

@losophy
Last active June 10, 2021 06:54
Show Gist options
  • Save losophy/f12f340a3a016b4385ccb30a31d7b989 to your computer and use it in GitHub Desktop.
Save losophy/f12f340a3a016b4385ccb30a31d7b989 to your computer and use it in GitHub Desktop.
skynet-1.4.0 timer实现代码
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);
}
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;
};

skynet_timer

从skynet-1.4.0中分离出来的timer实现代码。

关于skynet timer

skynet timer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment