]> git.hungrycats.org Git - linux/commitdiff
[PATCH] monotonic seqlock for cyclone timer
authorStephen Hemminger <shemminger@osdl.org>
Wed, 8 Oct 2003 05:07:25 +0000 (22:07 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Wed, 8 Oct 2003 05:07:25 +0000 (22:07 -0700)
Replace read/write lock used for cyclone timer monotonic_lock with seqlock.
Similar to locking used on xtime and monotonic_lock in timers/timer_tsc.c

arch/i386/kernel/timers/timer_cyclone.c

index 92ed6b1d8c834e6fd8be79461be18bd21b261c14..2dd4398ec037fe70e175bf6c37eefc6df484a189 100644 (file)
@@ -35,7 +35,7 @@ static u32* volatile cyclone_timer;   /* Cyclone MPMC0 register */
 static u32 last_cyclone_low;
 static u32 last_cyclone_high;
 static unsigned long long monotonic_base;
-static rwlock_t monotonic_lock = RW_LOCK_UNLOCKED;
+static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
 
 /* helper macro to atomically read both cyclone counter registers */
 #define read_cyclone_counter(low,high) \
@@ -51,7 +51,7 @@ static void mark_offset_cyclone(void)
        int count;
        unsigned long long this_offset, last_offset;
 
-       write_lock(&monotonic_lock);
+       write_seqlock(&monotonic_lock);
        last_offset = ((unsigned long long)last_cyclone_high<<32)|last_cyclone_low;
        
        spin_lock(&i8253_lock);
@@ -76,7 +76,7 @@ static void mark_offset_cyclone(void)
        /* update the monotonic base value */
        this_offset = ((unsigned long long)last_cyclone_high<<32)|last_cyclone_low;
        monotonic_base += (this_offset - last_offset) & CYCLONE_TIMER_MASK;
-       write_unlock(&monotonic_lock);
+       write_sequnlock(&monotonic_lock);
 
        /* calculate delay_at_last_interrupt */
        count = ((LATCH-1) - count) * TICK_SIZE;
@@ -117,12 +117,15 @@ static unsigned long long monotonic_clock_cyclone(void)
        u32 now_low, now_high;
        unsigned long long last_offset, this_offset, base;
        unsigned long long ret;
+       unsigned seq;
 
        /* atomically read monotonic base & last_offset */
-       read_lock_irq(&monotonic_lock);
-       last_offset = ((unsigned long long)last_cyclone_high<<32)|last_cyclone_low;
-       base = monotonic_base;
-       read_unlock_irq(&monotonic_lock);
+       do {
+               seq = read_seqbegin(&monotonic_lock);
+               last_offset = ((unsigned long long)last_cyclone_high<<32)|last_cyclone_low;
+               base = monotonic_base;
+       } while (read_seqretry(&monotonic_lock, seq));
+
 
        /* Read the cyclone counter */
        read_cyclone_counter(now_low,now_high);