From: don.hong Date: Mon, 31 Oct 2011 14:22:14 +0000 (+0900) Subject: [Title] Enhance the system clock to approximate to realtime smoothly X-Git-Tag: 2.2.1_release^2~182^2~35 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0856311464336c37600c21aace346c47290a025c;p=sdk%2Femulator%2Femulator-kernel.git [Title] Enhance the system clock to approximate to realtime smoothly [Type] Feature/BugFix/Enahncement [Module] kernel/time [Priority] [CQ#] [Redmine#] [Problem] [Cause] [Solution] Interpolate the time slip between host and kernel [TestCase] --- diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index a3b3fe91af98..b973c7d36eb5 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c @@ -57,7 +57,8 @@ int tick_is_oneshot_available(void) /* * Periodic tick */ -static void tick_periodic(int cpu) +#define UNDER_HYPERVISOR +void tick_periodic(int cpu) { if (tick_do_timer_cpu == cpu) { write_seqlock(&xtime_lock); @@ -65,28 +66,43 @@ static void tick_periodic(int cpu) /* Keep track of the next tick event */ tick_next_period = ktime_add(tick_next_period, tick_period); - if (0 == (jiffies & 0x7)) { - static __kernel_time_t rt; - static unsigned long rt_jiffies = INITIAL_JIFFIES; - - unsigned long tick = 1; - - struct timespec ts; - read_persistent_clock(&ts); + #ifdef UNDER_HYPERVISOR + { /* Compensate slow timer tick under hypervisor */ + static __kernel_time_t rt_sec; + static unsigned long rt_jiffies_sec = HZ; + static unsigned long rt_ticks_sec = HZ; + static unsigned long rt_tick = 0; + static unsigned long rt_current = 0; + static unsigned long rt_count = 1; + + unsigned long tick = rt_jiffies_sec * ++rt_tick / rt_ticks_sec - rt_current; + rt_current += tick; + do_timer(tick); - if (rt != ts.tv_sec) { - rt = ts.tv_sec; - rt_jiffies += HZ; - if (rt_jiffies>jiffies) { - tick=rt_jiffies-jiffies; - if (tick > HZ) - tick = 1; + if( 0 == --rt_count ) { + static int first = 2; + + struct timespec ts; + read_persistent_clock(&ts); + + if (rt_sec != ts.tv_sec) { + if (!first) { + rt_jiffies_sec = HZ + rt_jiffies_sec - rt_current; + rt_ticks_sec = rt_tick; + } else { + first--; + } + rt_sec = ts.tv_sec; + rt_tick = rt_current = 0; } + + rt_count = (!first && rt_ticks_sec > rt_tick + 3) ? (rt_ticks_sec - rt_tick) >> 2 : 1; } - do_timer(tick); } - else + #else do_timer(1); + #endif /* End of UNDER_HYPERVISOR */ + write_sequnlock(&xtime_lock); }