]> git.hungrycats.org Git - linux/commitdiff
[PATCH] monotonic seqlock for HPET timer
authorStephen Hemminger <shemminger@osdl.org>
Wed, 8 Oct 2003 05:07:34 +0000 (22:07 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Wed, 8 Oct 2003 05:07:34 +0000 (22:07 -0700)
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

index f14a6fc7dd06ef9d630b3fd9a05b32c529dcbc68..3beb26646dea83867f749de70de6dea4eb8bf18a 100644 (file)
@@ -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)