patch-2.4.0-test3 linux/arch/mips64/sgi-ip27/ip27-timer.c
Next file: linux/arch/mips64/tools/Makefile
Previous file: linux/arch/mips64/sgi-ip27/ip27-setup.c
Back to the patch index
Back to the overall index
- Lines: 144
- Date:
Mon Jul 10 14:22:00 2000
- Orig file:
v2.4.0-test2/linux/arch/mips64/sgi-ip27/ip27-timer.c
- Orig date:
Tue May 23 15:31:33 2000
diff -u --recursive --new-file v2.4.0-test2/linux/arch/mips64/sgi-ip27/ip27-timer.c linux/arch/mips64/sgi-ip27/ip27-timer.c
@@ -1,9 +1,7 @@
-/* $Id: ip27-timer.c,v 1.3 2000/02/18 09:54:40 ulfc Exp $
- *
- * Copytight (C) 1999 Ralf Baechle (ralf@gnu.org)
- * Copytight (C) 1999 Silicon Graphics, Inc.
+/*
+ * Copytight (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copytight (C) 1999, 2000 Silicon Graphics, Inc.
*/
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -36,10 +34,11 @@
#define CYCLES_PER_SEC (NSEC_PER_SEC/NSEC_PER_CYCLE)
#define CYCLES_PER_JIFFY (CYCLES_PER_SEC/HZ)
-static unsigned long ct_cur; /* What counter should be at next timer irq */
+static unsigned long ct_cur[NR_CPUS]; /* What counter should be at next timer irq */
static long last_rtc_update = 0; /* Last time the rtc clock got updated */
extern rwlock_t xtime_lock;
+extern volatile unsigned long lost_ticks;
static int set_rtc_mmss(unsigned long nowtime)
@@ -91,26 +90,28 @@
void rt_timer_interrupt(struct pt_regs *regs)
{
int cpu = smp_processor_id();
- int cpuA = ((cputoslice(smp_processor_id())) == 0);
- int user = user_mode(regs);
+ int cpuA = ((cputoslice(cpu)) == 0);
int irq = 7; /* XXX Assign number */
write_lock(&xtime_lock);
again:
LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0); /* Ack */
- ct_cur += CYCLES_PER_JIFFY;
- LOCAL_HUB_S(cpuA ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, ct_cur);
+ ct_cur[cpu] += CYCLES_PER_JIFFY;
+ LOCAL_HUB_S(cpuA ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, ct_cur[cpu]);
- if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur)
+ if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur[cpu])
goto again;
- kstat.irqs[cpu][irq]++; /* kstat+do_timer only for bootcpu? */
- do_timer(regs);
+ kstat.irqs[cpu][irq]++; /* kstat only for bootcpu? */
+
+ if (cpu == 0)
+ do_timer(regs);
#ifdef CONFIG_SMP
if (current->pid) {
unsigned int *inc, *inc2;
+ int user = user_mode(regs);
update_one_process(current, 1, user, !user, cpu);
if (--current->counter <= 0) {
@@ -119,7 +120,7 @@
}
if (user) {
- if (current->priority < DEF_PRIORITY) {
+ if (current->nice > 0) {
inc = &kstat.cpu_nice;
inc2 = &kstat.per_cpu_nice[cpu];
} else {
@@ -159,19 +160,51 @@
write_unlock(&xtime_lock);
}
+unsigned long inline do_gettimeoffset(void)
+{
+ unsigned long ct_cur1;
+ ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY;
+ return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000;
+}
+
void do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
+ unsigned long usec, sec;
read_lock_irqsave(&xtime_lock, flags);
- *tv = xtime;
+ usec = do_gettimeoffset();
+ {
+ unsigned long lost = lost_ticks;
+ if (lost)
+ usec += lost * (1000000 / HZ);
+ }
+ sec = xtime.tv_sec;
+ usec += xtime.tv_usec;
read_unlock_irqrestore(&xtime_lock, flags);
+
+ while (usec >= 1000000) {
+ usec -= 1000000;
+ sec++;
+ }
+
+ tv->tv_sec = sec;
+ tv->tv_usec = usec;
}
void do_settimeofday(struct timeval *tv)
{
write_lock_irq(&xtime_lock);
+ tv->tv_usec -= do_gettimeoffset();
+ tv->tv_usec -= lost_ticks * (1000000 / HZ);
+
+ while (tv->tv_usec < 0) {
+ tv->tv_usec += 1000000;
+ tv->tv_sec--;
+ }
+
xtime = *tv;
+ time_adjust = 0; /* stop active adjtime() */
time_state = TIME_BAD;
time_maxerror = MAXPHASE;
time_esterror = MAXPHASE;
@@ -286,15 +319,16 @@
* node and timeouts will not happen there.
*/
if (get_compact_nodeid() == cnode) {
+ int cpu = smp_processor_id();
LOCAL_HUB_S(PI_RT_EN_A, 1);
LOCAL_HUB_S(PI_RT_EN_B, 1);
LOCAL_HUB_S(PI_PROF_EN_A, 0);
LOCAL_HUB_S(PI_PROF_EN_B, 0);
- ct_cur = CYCLES_PER_JIFFY;
- LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur);
+ ct_cur[cpu] = CYCLES_PER_JIFFY;
+ LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur[cpu]);
LOCAL_HUB_S(PI_RT_COUNT, 0);
LOCAL_HUB_S(PI_RT_PEND_A, 0);
- LOCAL_HUB_S(PI_RT_COMPARE_B, ct_cur);
+ LOCAL_HUB_S(PI_RT_COMPARE_B, ct_cur[cpu]);
LOCAL_HUB_S(PI_RT_COUNT, 0);
LOCAL_HUB_S(PI_RT_PEND_B, 0);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)