diff options
Diffstat (limited to 'core/timebase.c')
-rw-r--r-- | core/timebase.c | 28 |
1 files changed, 8 insertions, 20 deletions
diff --git a/core/timebase.c b/core/timebase.c index a3c0fec..ca961c3 100644 --- a/core/timebase.c +++ b/core/timebase.c @@ -24,8 +24,8 @@ unsigned long tb_hz = 512000000; static void time_wait_poll(unsigned long duration) { - unsigned long remaining = duration; - unsigned long end = mftb() + duration; + unsigned long now = mftb(); + unsigned long end = now + duration; unsigned long period = msecs_to_tb(5); if (this_cpu()->tb_invalid) { @@ -33,7 +33,9 @@ static void time_wait_poll(unsigned long duration) return; } - while (tb_compare(mftb(), end) != TB_AAFTERB) { + while (tb_compare(now, end) != TB_AAFTERB) { + unsigned long remaining = end - now; + /* Call pollers periodically but not continually to avoid * bouncing cachelines due to lock contention. */ if (remaining >= period) { @@ -43,7 +45,7 @@ static void time_wait_poll(unsigned long duration) } else time_wait_nopoll(remaining); - cpu_relax(); + now = mftb(); } } @@ -64,28 +66,14 @@ void time_wait(unsigned long duration) void time_wait_nopoll(unsigned long duration) { - unsigned long end = mftb() + duration; - unsigned long min = usecs_to_tb(10); + unsigned long min_sleep = usecs_to_tb(10); if (this_cpu()->tb_invalid) { cpu_relax(); return; } - for (;;) { - uint64_t delay, tb = mftb(); - - if (tb_compare(tb, end) == TB_AAFTERB) - break; - delay = end - tb; - if (delay >= 0x7fffffff) - delay = 0x7fffffff; - if (delay >= min) { - mtspr(SPR_DEC, delay); - cpu_idle(cpu_wake_on_dec); - } else - cpu_relax(); - } + cpu_idle_delay(duration, min_sleep); } void time_wait_ms(unsigned long ms) |