From 1cbe6391867371a54183b2b3afbc358e2f8e9579 Mon Sep 17 00:00:00 2001 From: xjdrew Date: Wed, 25 Jun 2014 00:43:21 +0800 Subject: [PATCH 1/2] bugfix: time rewind --- skynet-src/skynet_timer.c | 51 +++++++++++++++++++++------------------ test/time.lua | 5 ++++ 2 files changed, 32 insertions(+), 24 deletions(-) create mode 100644 test/time.lua diff --git a/skynet-src/skynet_timer.c b/skynet-src/skynet_timer.c index 32b71f77..4ee0b70d 100644 --- a/skynet-src/skynet_timer.c +++ b/skynet-src/skynet_timer.c @@ -26,6 +26,8 @@ typedef void (*timer_execute_func)(void *ud,void *arg); #define TIME_NEAR_MASK (TIME_NEAR-1) #define TIME_LEVEL_MASK (TIME_LEVEL-1) +#define CENTISECOND_MASK 0x1ffffff + struct timer_event { uint32_t handle; int session; @@ -218,28 +220,41 @@ skynet_timeout(uint32_t handle, int time, int session) { return session; } -static uint32_t -_gettime(void) { - uint32_t t; +// centisecond: 1/100 second +static void +_systime(uint32_t *sec, uint32_t *cs) { #if !defined(__APPLE__) struct timespec ti; - clock_gettime(CLOCK_MONOTONIC, &ti); - t = (uint32_t)(ti.tv_sec & 0xffffff) * 100; - t += ti.tv_nsec / 10000000; + clock_gettime(CLOCK_REALTIME, &ti); + *sec = (uint32_t)ti.tv_sec; + *cs = (uint32_t)(ti.tv_nsec / 10000000); #else struct timeval tv; gettimeofday(&tv, NULL); - t = (uint32_t)(tv.tv_sec & 0xffffff) * 100; - t += tv.tv_usec / 10000; + *sec = tv.tv_sec; + *cs = tv.tv_usec / 10000; #endif - return t; +} + +static uint32_t +_gettime() { + uint32_t sec, cs; + _systime(&sec, &cs); + // if sec < TI->starttime, need to update TI->starttime? + // if(sec < TI->starttime) { + // skynet_error(NULL, "time diff error, change from %u -> %u", TI->starttime, sec); + // TI->starttime = sec; + // TI->current = cs; + // } + uint32_t diff = (sec - TI->starttime) & CENTISECOND_MASK; + return diff * 100 + cs; } void skynet_updatetime(void) { uint32_t ct = _gettime(); if (ct != TI->current) { - int diff = ct>=TI->current?ct-TI->current:(0xffffff+1)*100-TI->current+ct; + uint32_t diff = ct>=TI->current?ct-TI->current:(uint32_t)(CENTISECOND_MASK+1)*100-TI->current+ct; TI->current = ct; int i; for (i=0;icurrent = _gettime(); - -#if !defined(__APPLE__) - struct timespec ti; - clock_gettime(CLOCK_REALTIME, &ti); - uint32_t sec = (uint32_t)ti.tv_sec; -#else - struct timeval tv; - gettimeofday(&tv, NULL); - uint32_t sec = (uint32_t)tv.tv_sec; -#endif - uint32_t mono = _gettime() / 100; - - TI->starttime = sec - mono; + _systime(&TI->starttime, &TI->current); } + diff --git a/test/time.lua b/test/time.lua new file mode 100644 index 00000000..90784211 --- /dev/null +++ b/test/time.lua @@ -0,0 +1,5 @@ +local skynet = require "skynet" +skynet.start(function() + print(skynet.starttime()) + print(skynet.now()) +end) From e0d8b002260419279feea5775d44f3ad5047cf8d Mon Sep 17 00:00:00 2001 From: xjdrew Date: Wed, 25 Jun 2014 10:43:01 +0800 Subject: [PATCH 2/2] =?UTF-8?q?bugfix:=20ntp=E6=A0=A1=E9=AA=8C=E6=97=B6?= =?UTF-8?q?=E6=8A=8A=E6=97=B6=E9=97=B4=E5=BE=80=E5=90=8E=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- skynet-src/skynet_timer.c | 45 ++++++++++++++++++++++++--------------- test/time.lua | 17 +++++++++++++++ 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/skynet-src/skynet_timer.c b/skynet-src/skynet_timer.c index 4ee0b70d..43eb97e7 100644 --- a/skynet-src/skynet_timer.c +++ b/skynet-src/skynet_timer.c @@ -26,8 +26,6 @@ typedef void (*timer_execute_func)(void *ud,void *arg); #define TIME_NEAR_MASK (TIME_NEAR-1) #define TIME_LEVEL_MASK (TIME_LEVEL-1) -#define CENTISECOND_MASK 0x1ffffff - struct timer_event { uint32_t handle; int session; @@ -50,6 +48,8 @@ struct timer { int time; uint32_t current; uint32_t starttime; + uint64_t current_point; + uint64_t origin_point; }; static struct timer * TI = NULL; @@ -236,26 +236,34 @@ _systime(uint32_t *sec, uint32_t *cs) { #endif } -static uint32_t +static uint64_t _gettime() { - uint32_t sec, cs; - _systime(&sec, &cs); - // if sec < TI->starttime, need to update TI->starttime? - // if(sec < TI->starttime) { - // skynet_error(NULL, "time diff error, change from %u -> %u", TI->starttime, sec); - // TI->starttime = sec; - // TI->current = cs; - // } - uint32_t diff = (sec - TI->starttime) & CENTISECOND_MASK; - return diff * 100 + cs; + uint64_t t; +#if !defined(__APPLE__) + struct timespec ti; + clock_gettime(CLOCK_MONOTONIC, &ti); + t = ti.tv_sec * 100; + t += (uint32_t)(ti.tv_nsec / 10000000); +#else + struct timeval tv; + gettimeofday(&tv, NULL); + t = ti.tv_sec * 100; + t += (uint32_t)(tv.tv_usec / 10000); +#endif + return t; } void skynet_updatetime(void) { - uint32_t ct = _gettime(); - if (ct != TI->current) { - uint32_t diff = ct>=TI->current?ct-TI->current:(uint32_t)(CENTISECOND_MASK+1)*100-TI->current+ct; - TI->current = ct; + uint64_t cp = _gettime(); + if(cp < TI->current_point) { + skynet_error(NULL, "time diff error: change from %lld to %lld", cp, TI->current_point); + } else if (cp != TI->current_point) { + uint32_t diff = (uint32_t)(cp - TI->current_point); + TI->current_point = cp; + + // when cs > 0xffffffff(about 49710), time rewind + TI->current += diff; int i; for (i=0;istarttime, &TI->current); + uint64_t point = _gettime(); + TI->current_point = point; + TI->origin_point = point; } diff --git a/test/time.lua b/test/time.lua index 90784211..be02805c 100644 --- a/test/time.lua +++ b/test/time.lua @@ -2,4 +2,21 @@ local skynet = require "skynet" skynet.start(function() print(skynet.starttime()) print(skynet.now()) + + skynet.timeout(1, function() + print("in 1", skynet.now()) + end) + skynet.timeout(2, function() + print("in 2", skynet.now()) + end) + skynet.timeout(3, function() + print("in 3", skynet.now()) + end) + + skynet.timeout(4, function() + print("in 4", skynet.now()) + end) + skynet.timeout(100, function() + print("in 100", skynet.now()) + end) end)