patch-2.2.18 linux/arch/i386/kernel/time.c
Next file: linux/arch/i386/kernel/traps.c
Previous file: linux/arch/i386/kernel/smp.c
Back to the patch index
Back to the overall index
- Lines: 89
- Date:
Tue Sep 12 13:16:22 2000
- Orig file:
v2.2.17/arch/i386/kernel/time.c
- Orig date:
Sun Jun 11 21:44:09 2000
diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.17/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c
@@ -77,6 +77,9 @@
unsigned long fast_gettimeoffset_quotient=0;
extern rwlock_t xtime_lock;
+extern volatile unsigned long lost_ticks;
+
+spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
static inline unsigned long do_fast_gettimeoffset(void)
{
@@ -112,6 +115,8 @@
#ifndef CONFIG_X86_TSC
+spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
+
/* This function must be called with interrupts disabled
* It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs
*
@@ -156,6 +161,8 @@
*/
unsigned long jiffies_t;
+ /* gets recalled with irq locally disabled */
+ spin_lock(&i8253_lock);
/* timer count may underflow right here */
outb_p(0x00, 0x43); /* latch the count ASAP */
@@ -214,6 +221,7 @@
}
} else
jiffies_p = jiffies_t;
+ spin_unlock(&i8253_lock);
count_p = count;
@@ -237,7 +245,6 @@
*/
void do_gettimeofday(struct timeval *tv)
{
- extern volatile unsigned long lost_ticks;
unsigned long flags;
unsigned long usec, sec;
@@ -271,6 +278,7 @@
* would have done, and then undo it!
*/
tv->tv_usec -= do_gettimeoffset();
+ tv->tv_usec -= lost_ticks * (1000000 / HZ);
while (tv->tv_usec < 0) {
tv->tv_usec += 1000000;
@@ -301,6 +309,8 @@
int real_seconds, real_minutes, cmos_minutes;
unsigned char save_control, save_freq_select;
+ /* gets recalled with irq locally disabled */
+ spin_lock(&rtc_lock);
save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
@@ -346,6 +356,7 @@
*/
CMOS_WRITE(save_control, RTC_CONTROL);
CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+ spin_unlock(&rtc_lock);
return retval;
}
@@ -447,10 +458,19 @@
rdtscl(last_tsc_low);
+#if 0 /*
+ * SUBTLE: this is not necessary from here because it's implicit in the
+ * write xtime_lock.
+ */
+ spin_lock(&i8253_lock);
+#endif
outb_p(0x00, 0x43); /* latch the count ASAP */
count = inb_p(0x40); /* read the latched count */
count |= inb(0x40) << 8;
+#if 0
+ spin_unlock(&i8253_lock);
+#endif
count = ((LATCH-1) - count) * TICK_SIZE;
delay_at_last_interrupt = (count + LATCH/2) / LATCH;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)