From 43fc52f39db31cb0daa901d89b852a8bfcd19d35 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 7 Oct 2003 22:07:34 -0700 Subject: [PATCH] [PATCH] monotonic seqlock for HPET timer Replace read/write lock used for HPET timer monotonic_lock with seqlock. Similar to locking used on xtime and monotonic_lock in timers/timer_tsc.c --- arch/i386/kernel/timers/timer_hpet.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/arch/i386/kernel/timers/timer_hpet.c b/arch/i386/kernel/timers/timer_hpet.c index f14a6fc7dd06..3beb26646dea 100644 --- a/arch/i386/kernel/timers/timer_hpet.c +++ b/arch/i386/kernel/timers/timer_hpet.c @@ -24,7 +24,7 @@ static unsigned long hpet_last; /* hpet counter value at last tick*/ static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */ static unsigned long long monotonic_base; -static rwlock_t monotonic_lock = RW_LOCK_UNLOCKED; +static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED; /* convert from cycles(64bits) => nanoseconds (64bits) * basic equation: @@ -57,12 +57,14 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc) static unsigned long long monotonic_clock_hpet(void) { unsigned long long last_offset, this_offset, base; + unsigned seq; /* atomically read monotonic base & last_offset */ - read_lock_irq(&monotonic_lock); - last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; - base = monotonic_base; - read_unlock_irq(&monotonic_lock); + do { + seq = read_seqbegin(&monotonic_lock); + last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; + base = monotonic_base; + } while (read_seqretry(&monotonic_lock, seq)); /* Read the Time Stamp Counter */ rdtscll(this_offset); @@ -99,7 +101,7 @@ static void mark_offset_hpet(void) unsigned long long this_offset, last_offset; unsigned long offset; - write_lock(&monotonic_lock); + write_seqlock(&monotonic_lock); last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; rdtsc(last_tsc_low, last_tsc_high); @@ -113,7 +115,7 @@ static void mark_offset_hpet(void) /* update the monotonic base value */ this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; monotonic_base += cycles_2_ns(this_offset - last_offset); - write_unlock(&monotonic_lock); + write_sequnlock(&monotonic_lock); } void delay_hpet(unsigned long loops) -- 2.39.5