shift time before dispatch timer message

This commit is contained in:
Cloud Wu
2014-03-14 15:05:41 +08:00
parent 5fa3040a85
commit 84ec9c4123
2 changed files with 54 additions and 32 deletions

View File

@@ -11,7 +11,17 @@ local function wakeup(co)
end end
end end
local function test()
skynet.timeout(10, function() print("test timeout 10") end)
for i=1,10 do
print("test sleep",i,skynet.now())
skynet.sleep(1)
end
end
skynet.start(function() skynet.start(function()
test()
skynet.fork(wakeup, coroutine.running()) skynet.fork(wakeup, coroutine.running())
skynet.timeout(300, function() timeout "Hello World" end) skynet.timeout(300, function() timeout "Hello World" end)
for i = 1, 10 do for i = 1, 10 do
@@ -20,4 +30,5 @@ skynet.start(function()
end end
skynet.exit() skynet.exit()
print("Test timer exit") print("Test timer exit")
end) end)

View File

@@ -102,16 +102,36 @@ timer_add(struct timer *T,void *arg,size_t sz,int time)
__sync_lock_release(&T->lock); __sync_lock_release(&T->lock);
} }
static void static void
timer_execute(struct timer *T) timer_shift(struct timer *T) {
{ int mask = TIME_NEAR;
while (__sync_lock_test_and_set(&T->lock,1)) {}; int time = (++T->time) >> TIME_NEAR_SHIFT;
int idx=T->time & TIME_NEAR_MASK; int i=0;
struct timer_node *current;
int mask,i,time; while ((T->time & (mask-1))==0) {
int idx=time & TIME_LEVEL_MASK;
if (idx!=0) {
--idx;
struct timer_node *current = link_clear(&T->t[i][idx]);
while (current) {
struct timer_node *temp=current->next;
add_node(T,current);
current=temp;
}
break;
}
mask <<= TIME_LEVEL_SHIFT;
time >>= TIME_LEVEL_SHIFT;
++i;
}
}
static inline void
timer_execute(struct timer *T) {
int idx = T->time & TIME_NEAR_MASK;
while (T->near[idx].head.next) { while (T->near[idx].head.next) {
current=link_clear(&T->near[idx]); struct timer_node *current = link_clear(&T->near[idx]);
do { do {
struct timer_event * event = (struct timer_event *)(current+1); struct timer_event * event = (struct timer_event *)(current+1);
@@ -128,29 +148,20 @@ timer_execute(struct timer *T)
free(temp); free(temp);
} while (current); } while (current);
} }
}
++T->time;
static void
mask = TIME_NEAR; timer_update(struct timer *T)
time = T->time >> TIME_NEAR_SHIFT; {
i=0; while (__sync_lock_test_and_set(&T->lock,1)) {};
while ((T->time & (mask-1))==0) { // try to dispatch timeout 0 (rare condition)
idx=time & TIME_LEVEL_MASK; timer_execute(T);
if (idx!=0) {
--idx; // shift time first, and then dispatch timer message
current=link_clear(&T->t[i][idx]); timer_shift(T);
while (current) { timer_execute(T);
struct timer_node *temp=current->next;
add_node(T,current);
current=temp;
}
break;
}
mask <<= TIME_LEVEL_SHIFT;
time >>= TIME_LEVEL_SHIFT;
++i;
}
__sync_lock_release(&T->lock); __sync_lock_release(&T->lock);
} }
@@ -225,7 +236,7 @@ skynet_updatetime(void) {
TI->current = ct; TI->current = ct;
int i; int i;
for (i=0;i<diff;i++) { for (i=0;i<diff;i++) {
timer_execute(TI); timer_update(TI);
} }
} }
} }