mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 03:53:09 +00:00
optimize timer
This commit is contained in:
@@ -16,6 +16,9 @@
|
||||
|
||||
typedef void (*timer_execute_func)(void *ud,void *arg);
|
||||
|
||||
#define LOCK(q) while (__sync_lock_test_and_set(&(q)->lock,1)) {}
|
||||
#define UNLOCK(q) __sync_lock_release(&(q)->lock);
|
||||
|
||||
#define TIME_NEAR_SHIFT 8
|
||||
#define TIME_NEAR (1 << TIME_NEAR_SHIFT)
|
||||
#define TIME_LEVEL_SHIFT 6
|
||||
@@ -50,8 +53,7 @@ struct timer {
|
||||
static struct timer * TI = NULL;
|
||||
|
||||
static inline struct timer_node *
|
||||
link_clear(struct link_list *list)
|
||||
{
|
||||
link_clear(struct link_list *list) {
|
||||
struct timer_node * ret = list->head.next;
|
||||
list->head.next = 0;
|
||||
list->tail = &(list->head);
|
||||
@@ -60,23 +62,20 @@ link_clear(struct link_list *list)
|
||||
}
|
||||
|
||||
static inline void
|
||||
link(struct link_list *list,struct timer_node *node)
|
||||
{
|
||||
link(struct link_list *list,struct timer_node *node) {
|
||||
list->tail->next = node;
|
||||
list->tail = node;
|
||||
node->next=0;
|
||||
}
|
||||
|
||||
static void
|
||||
add_node(struct timer *T,struct timer_node *node)
|
||||
{
|
||||
add_node(struct timer *T,struct timer_node *node) {
|
||||
int time=node->expire;
|
||||
int current_time=T->time;
|
||||
|
||||
if ((time|TIME_NEAR_MASK)==(current_time|TIME_NEAR_MASK)) {
|
||||
link(&T->near[time&TIME_NEAR_MASK],node);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
int i;
|
||||
int mask=TIME_NEAR << TIME_LEVEL_SHIFT;
|
||||
for (i=0;i<3;i++) {
|
||||
@@ -90,21 +89,21 @@ add_node(struct timer *T,struct timer_node *node)
|
||||
}
|
||||
|
||||
static void
|
||||
timer_add(struct timer *T,void *arg,size_t sz,int time)
|
||||
{
|
||||
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);
|
||||
|
||||
while (__sync_lock_test_and_set(&T->lock,1)) {};
|
||||
LOCK(T);
|
||||
|
||||
node->expire=time+T->time;
|
||||
add_node(T,node);
|
||||
|
||||
__sync_lock_release(&T->lock);
|
||||
UNLOCK(T);
|
||||
}
|
||||
|
||||
static void
|
||||
timer_shift(struct timer *T) {
|
||||
LOCK(T);
|
||||
int mask = TIME_NEAR;
|
||||
int time = (++T->time) >> TIME_NEAR_SHIFT;
|
||||
int i=0;
|
||||
@@ -125,50 +124,57 @@ timer_shift(struct timer *T) {
|
||||
time >>= TIME_LEVEL_SHIFT;
|
||||
++i;
|
||||
}
|
||||
UNLOCK(T);
|
||||
}
|
||||
|
||||
static inline void
|
||||
dispatch_list(struct timer_node *current) {
|
||||
do {
|
||||
struct timer_event * event = (struct timer_event *)(current+1);
|
||||
struct skynet_message message;
|
||||
message.source = 0;
|
||||
message.session = event->session;
|
||||
message.data = NULL;
|
||||
message.sz = PTYPE_RESPONSE << HANDLE_REMOTE_SHIFT;
|
||||
|
||||
skynet_context_push(event->handle, &message);
|
||||
|
||||
struct timer_node * temp = current;
|
||||
current=current->next;
|
||||
skynet_free(temp);
|
||||
} while (current);
|
||||
}
|
||||
|
||||
static inline void
|
||||
timer_execute(struct timer *T) {
|
||||
LOCK(T);
|
||||
int idx = T->time & TIME_NEAR_MASK;
|
||||
|
||||
while (T->near[idx].head.next) {
|
||||
struct timer_node *current = link_clear(&T->near[idx]);
|
||||
|
||||
do {
|
||||
struct timer_event * event = (struct timer_event *)(current+1);
|
||||
struct skynet_message message;
|
||||
message.source = 0;
|
||||
message.session = event->session;
|
||||
message.data = NULL;
|
||||
message.sz = PTYPE_RESPONSE << HANDLE_REMOTE_SHIFT;
|
||||
|
||||
skynet_context_push(event->handle, &message);
|
||||
|
||||
struct timer_node * temp = current;
|
||||
current=current->next;
|
||||
skynet_free(temp);
|
||||
} while (current);
|
||||
UNLOCK(T);
|
||||
// dispatch_list don't need lock T
|
||||
dispatch_list(current);
|
||||
LOCK(T);
|
||||
}
|
||||
|
||||
UNLOCK(T);
|
||||
}
|
||||
|
||||
static void
|
||||
timer_update(struct timer *T)
|
||||
{
|
||||
while (__sync_lock_test_and_set(&T->lock,1)) {};
|
||||
|
||||
timer_update(struct timer *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);
|
||||
|
||||
__sync_lock_release(&T->lock);
|
||||
}
|
||||
|
||||
static struct timer *
|
||||
timer_create_timer()
|
||||
{
|
||||
timer_create_timer() {
|
||||
struct timer *r=(struct timer *)skynet_malloc(sizeof(struct timer));
|
||||
memset(r,0,sizeof(*r));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user