static irqreturn_t timer_interrupt(int dummy, void *dev_id) { /* last time the cmos clock got updated */ static long last_rtc_update; #ifndef CONFIG_SMP profile_tick(CPU_PROFILING); #endif /* Protect counter clear so that do_gettimeoffset works */ write_seqlock(&xtime_lock); clear_clock_irq(); do_timer(1); /* Determine when to update the Mostek clock. */ if (ntp_synced() && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { if (set_rtc_mmss(xtime.tv_sec) == 0) last_rtc_update = xtime.tv_sec; else last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ } write_sequnlock(&xtime_lock); #ifndef CONFIG_SMP update_process_times(user_mode(get_irq_regs())); #endif return IRQ_HANDLED; }
/* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ static irqreturn_t timer_interrupt(int irq, void *dummy) { do_timer(1); #ifndef CONFIG_SMP update_process_times(user_mode(get_irq_regs())); #endif profile_tick(CPU_PROFILING); #ifdef CONFIG_HEARTBEAT /* use power LED as a heartbeat instead -- much more useful for debugging -- based on the version for PReP by Cort */ /* acts like an actual heart beat -- ie thump-thump-pause... */ if (mach_heartbeat) { static unsigned cnt = 0, period = 0, dist = 0; if (cnt == 0 || cnt == dist) mach_heartbeat( 1 ); else if (cnt == 7 || cnt == dist+7) mach_heartbeat( 0 ); if (++cnt > period) { cnt = 0; /* The hyperbolic function below modifies the heartbeat period * length in dependency of the current (5min) load. It goes * through the points f(0)=126, f(1)=86, f(5)=51, * f(inf)->30. */ period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30; dist = period / 4; } } #endif /* CONFIG_HEARTBEAT */ return IRQ_HANDLED; }
irqreturn_t timer_interrupt (int irq, void *dev_id) { unsigned long next; next = get_linux_timer(); again: while ((signed long)(get_ccount() - next) > 0) { profile_tick(CPU_PROFILING); #ifndef CONFIG_SMP update_process_times(user_mode(get_irq_regs())); #endif xtime_update(1); /* */ /* */ next += CCOUNT_PER_JIFFY; set_linux_timer(next); } /* */ platform_heartbeat(); /* */ if ((signed long)(get_ccount() - next) > 0) goto again; return IRQ_HANDLED; }
/* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) { #ifndef CONFIG_SMP profile_tick(CPU_PROFILING, regs); #endif do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif /* * If we have an externally synchronized Linux clock, then update * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to 500 ms before the new second starts. */ if ((time_status & STA_UNSYNC) == 0 && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned)TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned)TICK_SIZE) / 2) { if (set_rtc_mmss(xtime.tv_sec) == 0) last_rtc_update = xtime.tv_sec; else /* do it again in 60 s */ last_rtc_update = xtime.tv_sec - 600; } /* As we return to user mode fire off the other CPU schedulers.. this is basically because we don't yet share IRQ's around. This message is rigged to be safe on the 386 - basically it's a hack, so don't look closely for now.. */ #ifdef CONFIG_SMP smp_local_timer_interrupt(regs); #endif }
static void tick_nohz_handler(struct clock_event_device *dev) { struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched); struct pt_regs *regs = get_irq_regs(); int cpu = smp_processor_id(); ktime_t now = ktime_get(); dev->next_event.tv64 = KTIME_MAX; if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) tick_do_timer_cpu = cpu; if (tick_do_timer_cpu == cpu) tick_do_update_jiffies64(now); if (ts->tick_stopped) { touch_softlockup_watchdog(); ts->idle_jiffies++; } update_process_times(user_mode(regs)); profile_tick(CPU_PROFILING); while (tick_nohz_reprogram(ts, now)) { now = ktime_get(); tick_do_update_jiffies64(now); } }
/* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs *regs) { /* last time the cmos clock got updated */ static long last_rtc_update = 0; write_seqlock(&xtime_lock); do_timer(regs); do_leds(); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif profile_tick(CPU_PROFILING, regs); /* * If we have an externally synchronized Linux clock, then update * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to 500 ms before the new second starts. */ if ((time_status & STA_UNSYNC) == 0 && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned)TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned)TICK_SIZE) / 2) { if (set_rtc_mmss(xtime.tv_sec) == 0) last_rtc_update = xtime.tv_sec; else /* Do it again in 60s. */ last_rtc_update = xtime.tv_sec - 600; } write_sequnlock(&xtime_lock); return IRQ_HANDLED; }
void coldfire_profile_tick(int irq, void *dummy, struct pt_regs *regs) { /* Reset ColdFire timer2 */ mcf_proftp->ter = MCFTIMER_TER_CAP | MCFTIMER_TER_REF; if (current->pid) profile_tick(CPU_PROFILING, regs); }
/*==========================================================================* * Name: smp_local_timer_interrupt * * Description: Local timer interrupt handler. It does both profiling and * process statistics/rescheduling. * We do profiling in every local tick, statistics/rescheduling * happen only every 'profiling multiplier' ticks. The default * multiplier is 1 and it can be changed by writing the new * multiplier value into /proc/profile. * * Born on Date: 2002.02.05 * * Arguments: *regs - a pointer to the saved regster info * * Returns: void (cannot fail) * * Original: arch/i386/kernel/apic.c * * Modification log: * Date Who Description * ---------- --- -------------------------------------------------------- * 2003-06-24 hy use per_cpu structure. *==========================================================================*/ void smp_local_timer_interrupt(void) { int user = user_mode(get_irq_regs()); int cpu_id = smp_processor_id(); /* * The profiling function is SMP safe. (nothing can mess * around with "current", and the profiling counters are * updated with atomic operations). This is especially * useful with a profiling multiplier != 1 */ profile_tick(CPU_PROFILING); if (--per_cpu(prof_counter, cpu_id) <= 0) { /* * The multiplier may have changed since the last time we got * to this point as a result of the user writing to * /proc/profile. In this case we need to adjust the APIC * timer accordingly. * * Interrupts are already masked off at this point. */ per_cpu(prof_counter, cpu_id) = per_cpu(prof_multiplier, cpu_id); if (per_cpu(prof_counter, cpu_id) != per_cpu(prof_old_multiplier, cpu_id)) { per_cpu(prof_old_multiplier, cpu_id) = per_cpu(prof_counter, cpu_id); } update_process_times(user); } }
static irqreturn_t timer_interrupt(int dummy, void *dev_id) { #ifndef CONFIG_SMP profile_tick(CPU_PROFILING); #endif <<<<<<< HEAD
/* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ static irqreturn_t timer_interrupt(int irq, void *dummy) { profile_tick(CPU_PROFILING); /* * Here we are in the timer irq handler. We just have irqs locally * disabled but we don't know if the timer_bh is running on the other * CPU. We need to avoid to SMP race with it. NOTE: we don't need * the irq version of write_lock because as just said we have irq * locally disabled. -arca */ write_seqlock(&xtime_lock); do_timer(1); #ifdef CONFIG_HEARTBEAT static unsigned short n; n++; __set_LEDS(n); #endif /* CONFIG_HEARTBEAT */ write_sequnlock(&xtime_lock); update_process_times(user_mode(get_irq_regs())); return IRQ_HANDLED; }
/* * handle_timer_tick() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ void handle_timer_tick(struct pt_regs *regs) { do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif profile_tick(CPU_PROFILING, regs); #ifdef CONFIG_HEARTBEAT if (sh_mv.mv_heartbeat != NULL) sh_mv.mv_heartbeat(); #endif /* * If we have an externally synchronized Linux clock, then update * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to 500 ms before the new second starts. */ if (ntp_synced() && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { if (rtc_set_time(xtime.tv_sec) == 0) last_rtc_update = xtime.tv_sec; else /* do it again in 60s */ last_rtc_update = xtime.tv_sec - 600; } }
irqreturn_t timer_interrupt (int irq, void *dev_id) { unsigned long next; next = get_linux_timer(); again: while ((signed long)(get_ccount() - next) > 0) { profile_tick(CPU_PROFILING); #ifndef CONFIG_SMP update_process_times(user_mode(get_irq_regs())); #endif xtime_update(1); /* Linux handler in kernel/time/timekeeping */ /* Note that writing CCOMPARE clears the interrupt. */ next += CCOUNT_PER_JIFFY; set_linux_timer(next); } /* Allow platform to do something useful (Wdog). */ platform_heartbeat(); /* Make sure we didn't miss any tick... */ if ((signed long)(get_ccount() - next) > 0) goto again; return IRQ_HANDLED; }
static irqreturn_t timer_interrupt(int irq, void *dummy) { xtime_update(1); update_process_times(user_mode(get_irq_regs())); profile_tick(CPU_PROFILING); #ifdef CONFIG_HEARTBEAT /* */ /* */ if (mach_heartbeat) { static unsigned cnt = 0, period = 0, dist = 0; if (cnt == 0 || cnt == dist) mach_heartbeat( 1 ); else if (cnt == 7 || cnt == dist+7) mach_heartbeat( 0 ); if (++cnt > period) { cnt = 0; /* */ period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30; dist = period / 4; } } #endif /* */ return IRQ_HANDLED; }
static irqreturn_t timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) { unsigned long new_itm; if (unlikely(cpu_is_offline(smp_processor_id()))) { return IRQ_HANDLED; } platform_timer_interrupt(irq, dev_id, regs); new_itm = local_cpu_data->itm_next; if (!time_after(ia64_get_itc(), new_itm)) printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n", ia64_get_itc(), new_itm); profile_tick(CPU_PROFILING, regs); while (1) { update_process_times(user_mode(regs)); new_itm += local_cpu_data->itm_delta; if (smp_processor_id() == TIME_KEEPER_ID) { /* * Here we are in the timer irq handler. We have irqs locally * disabled, but we don't know if the timer_bh is running on * another CPU. We need to avoid to SMP race by acquiring the * xtime_lock. */ write_seqlock(&xtime_lock); do_timer(regs); local_cpu_data->itm_next = new_itm; write_sequnlock(&xtime_lock); } else local_cpu_data->itm_next = new_itm; if (time_after(new_itm, ia64_get_itc())) break; } do { /* * If we're too close to the next clock tick for * comfort, we increase the safety margin by * intentionally dropping the next tick(s). We do NOT * update itm.next because that would force us to call * do_timer() which in turn would let our clock run * too fast (with the potentially devastating effect * of losing monotony of time). */ while (!time_after(new_itm, ia64_get_itc() + local_cpu_data->itm_delta/2)) new_itm += local_cpu_data->itm_delta; ia64_set_itm(new_itm); /* double check, in case we got hit by a (slow) PMI: */ } while (time_after_eq(ia64_get_itc(), new_itm)); return IRQ_HANDLED; }
/* * We keep time on PA-RISC Linux by using the Interval Timer which is * a pair of registers; one is read-only and one is write-only; both * accessed through CR16. The read-only register is 32 or 64 bits wide, * and increments by 1 every CPU clock tick. The architecture only * guarantees us a rate between 0.5 and 2, but all implementations use a * rate of 1. The write-only register is 32-bits wide. When the lowest * 32 bits of the read-only register compare equal to the write-only * register, it raises a maskable external interrupt. Each processor has * an Interval Timer of its own and they are not synchronised. * * We want to generate an interrupt every 1/HZ seconds. So we program * CR16 to interrupt every @clocktick cycles. The it_value in cpu_data * is programmed with the intended time of the next tick. We can be * held off for an arbitrarily long period of time by interrupts being * disabled, so we may miss one or more ticks. */ irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id) { unsigned long now; unsigned long next_tick; unsigned long ticks_elapsed = 0; unsigned int cpu = smp_processor_id(); struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu); /* gcc can optimize for "read-only" case with a local clocktick */ unsigned long cpt = clocktick; profile_tick(CPU_PROFILING); /* Initialize next_tick to the old expected tick time. */ next_tick = cpuinfo->it_value; /* Calculate how many ticks have elapsed. */ do { ++ticks_elapsed; next_tick += cpt; now = mfctl(16); } while (next_tick - now > cpt); /* Store (in CR16 cycles) up to when we are accounting right now. */ cpuinfo->it_value = next_tick; /* Go do system house keeping. */ if (cpu == 0) xtime_update(ticks_elapsed); update_process_times(user_mode(get_irq_regs())); /* Skip clockticks on purpose if we know we would miss those. * The new CR16 must be "later" than current CR16 otherwise * itimer would not fire until CR16 wrapped - e.g 4 seconds * later on a 1Ghz processor. We'll account for the missed * ticks on the next timer interrupt. * We want IT to fire modulo clocktick even if we miss/skip some. * But those interrupts don't in fact get delivered that regularly. * * "next_tick - now" will always give the difference regardless * if one or the other wrapped. If "now" is "bigger" we'll end up * with a very large unsigned number. */ while (next_tick - mfctl(16) > cpt) next_tick += cpt; /* Program the IT when to deliver the next interrupt. * Only bottom 32-bits of next_tick are writable in CR16! * Timer interrupt will be delivered at least a few hundred cycles * after the IT fires, so if we are too close (<= 500 cycles) to the * next cycle, simply skip it. */ if (next_tick - mfctl(16) <= 500) next_tick += cpt; mtctl(next_tick, 16); return IRQ_HANDLED; }
/* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ static irqreturn_t timer_interrupt(int irq, void *dummy) { /* last time the cmos clock got updated */ static long last_rtc_update=0; /* may need to kick the hardware timer */ if (mach_tick) mach_tick(); write_seqlock(&xtime_lock); do_timer(1); #ifndef CONFIG_SMP update_process_times(user_mode(get_irq_regs())); #endif if (current->pid) profile_tick(CPU_PROFILING); /* * If we have an externally synchronized Linux clock, then update * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to 500 ms before the new second starts. */ if (ntp_synced() && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { if (set_rtc_mmss(xtime.tv_sec) == 0) last_rtc_update = xtime.tv_sec; else last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ } #ifdef CONFIG_HEARTBEAT /* use power LED as a heartbeat instead -- much more useful for debugging -- based on the version for PReP by Cort */ /* acts like an actual heart beat -- ie thump-thump-pause... */ if (mach_heartbeat) { static unsigned cnt = 0, period = 0, dist = 0; if (cnt == 0 || cnt == dist) mach_heartbeat( 1 ); else if (cnt == 7 || cnt == dist+7) mach_heartbeat( 0 ); if (++cnt > period) { cnt = 0; /* The hyperbolic function below modifies the heartbeat period * length in dependency of the current (5min) load. It goes * through the points f(0)=126, f(1)=86, f(5)=51, * f(inf)->30. */ period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30; dist = period / 4; } } #endif /* CONFIG_HEARTBEAT */ write_sequnlock(&xtime_lock); return(IRQ_HANDLED); }
irqreturn_t mcfslt_profile_tick(int irq, void *dummy) { /* Reset Slice Timer 1 */ __raw_writel(MCFSLT_SSR_BE | MCFSLT_SSR_TE, PA(MCFSLT_SSR)); if (current->pid) profile_tick(CPU_PROFILING); return IRQ_HANDLED; }
/* * Use the other timer to provide high accuracy profiling info. */ irqreturn_t coldfire_profile_tick(int irq, void *dummy) { /* Reset ColdFire timer2 */ __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, PA(MCFTIMER_TER)); if (current->pid) profile_tick(CPU_PROFILING); return IRQ_HANDLED; }
/* * Kernel system timer support. */ void timer_tick(void) { profile_tick(CPU_PROFILING); xtime_update(1); #ifndef CONFIG_SMP update_process_times(user_mode(get_irq_regs())); #endif }
void h8300_timer_tick(void) { if (current->pid) profile_tick(CPU_PROFILING); write_atomic_seqlock(&xtime_lock); do_timer(1); write_atomic_sequnlock(&xtime_lock); update_process_times(user_mode(get_irq_regs())); }
static irqreturn_t timer_interrupt (int irq, void *dev_id) { unsigned long new_itm; if (cpu_is_offline(smp_processor_id())) { return IRQ_HANDLED; } platform_timer_interrupt(irq, dev_id); new_itm = local_cpu_data->itm_next; if (!time_after(ia64_get_itc(), new_itm)) printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n", ia64_get_itc(), new_itm); profile_tick(CPU_PROFILING); while (1) { update_process_times(user_mode(get_irq_regs())); new_itm += local_cpu_data->itm_delta; if (smp_processor_id() == time_keeper_id) xtime_update(1); local_cpu_data->itm_next = new_itm; if (time_after(new_itm, ia64_get_itc())) break; /* * Allow IPIs to interrupt the timer loop. */ local_irq_enable(); local_irq_disable(); } do { /* * If we're too close to the next clock tick for * comfort, we increase the safety margin by * intentionally dropping the next tick(s). We do NOT * update itm.next because that would force us to call * xtime_update() which in turn would let our clock run * too fast (with the potentially devastating effect * of losing monotony of time). */ while (!time_after(new_itm, ia64_get_itc() + local_cpu_data->itm_delta/2)) new_itm += local_cpu_data->itm_delta; ia64_set_itm(new_itm); /* double check, in case we got hit by a (slow) PMI: */ } while (time_after_eq(ia64_get_itc(), new_itm)); return IRQ_HANDLED; }
/* * We rearm the timer until we get disabled by the idle code. * Called with interrupts disabled and timer->base->cpu_base->lock held. */ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) { struct tick_sched *ts = container_of(timer, struct tick_sched, sched_timer); struct pt_regs *regs = get_irq_regs(); ktime_t now = ktime_get(); int cpu = smp_processor_id(); #ifdef CONFIG_NO_HZ /* * Check if the do_timer duty was dropped. We don't care about * concurrency: This happens only when the cpu in charge went * into a long sleep. If two cpus happen to assign themself to * this duty, then the jiffies update is still serialized by * xtime_lock. */ if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) tick_do_timer_cpu = cpu; #endif /* Check, if the jiffies need an update */ if (tick_do_timer_cpu == cpu) tick_do_update_jiffies64(now); /* * Do not call, when we are not in irq context and have * no valid regs pointer */ if (regs) { /* * When we are idle and the tick is stopped, we have to touch * the watchdog as we might not schedule for a really long * time. This happens on complete idle SMP systems while * waiting on the login prompt. We also increment the "start of * idle" jiffy stamp so the idle accounting adjustment we do * when we go busy again does not account too much ticks. */ if (ts->tick_stopped) { touch_softlockup_watchdog(); ts->idle_jiffies++; } update_process_times(user_mode(regs)); profile_tick(CPU_PROFILING); #ifdef CONFIG_MSM_RUN_QUEUE_STATS /* update rq_avg report (for mpdecision) */ if (tick_do_timer_cpu == smp_processor_id()) msm_update_rq_stats(); #endif } hrtimer_forward(timer, now, tick_period); return HRTIMER_RESTART; }
/* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs) { /* may need to kick the hardware timer */ platform_timer_eoi(); do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif profile_tick(CPU_PROFILING, regs); }
/* * Kernel system timer support. */ void timer_tick(void) { profile_tick(CPU_PROFILING); do_leds(); write_seqlock(&xtime_lock); do_timer(1); write_sequnlock(&xtime_lock); #ifndef CONFIG_SMP update_process_times(user_mode(get_irq_regs())); #endif }
/* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "xtime_update()" routine every clocktick */ irqreturn_t arch_timer_interrupt(int irq, void *dummy) { if (current->pid) profile_tick(CPU_PROFILING); xtime_update(1); update_process_times(user_mode(get_irq_regs())); return(IRQ_HANDLED); }
void cris_do_profile(struct pt_regs* regs) { #ifdef CONFIG_SYSTEM_PROFILER cris_profile_sample(regs); #endif #ifdef CONFIG_PROFILING profile_tick(CPU_PROFILING); #endif }
inline void smp_local_timer_interrupt(struct pt_regs * regs) { int cpu = smp_processor_id(); #ifdef CONFIG_HIGH_RES_TIMERS if (! per_cpu(prof_counter, cpu)) do_hr_timer_int(); #endif profile_tick(CPU_PROFILING, regs); if (--per_cpu(prof_counter, cpu) <= 0) { /* * The multiplier may have changed since the last time we got * to this point as a result of the user writing to * /proc/profile. In this case we need to adjust the APIC * timer accordingly. * * Interrupts are already masked off at this point. */ per_cpu(prof_counter, cpu) = per_cpu(prof_multiplier, cpu); if (per_cpu(prof_counter, cpu) != per_cpu(prof_old_multiplier, cpu)) { __setup_APIC_LVTT( calibration_result/ per_cpu(prof_counter, cpu)); per_cpu(prof_old_multiplier, cpu) = per_cpu(prof_counter, cpu); #ifdef CONFIG_HIGH_RES_TIMERS return; #endif } #ifdef CONFIG_HIGH_RES_TIMERS apic_write_around(APIC_TMICT, calibration_result / per_cpu(prof_counter, cpu)); #else #ifdef CONFIG_SMP update_process_times(user_mode(regs)); #endif #endif } /* * We take the 'long' return path, and there every subsystem * grabs the apropriate locks (kernel lock/ irq lock). * * we might want to decouple profiling from the 'long path', * and do the profiling totally in assembly. * * Currently this isn't too much of an issue (performance wise), * we can take more than 100K local irqs per second on a 100 MHz P5. */ }
irqreturn_t timer_interrupt(int irq, void *dummy) { xtime_update(1); #ifdef CONFIG_IPIPE update_root_process_times(get_irq_regs()); #else update_process_times(user_mode(get_irq_regs())); #endif profile_tick(CPU_PROFILING); return IRQ_HANDLED; }
/* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "xtime_update()" routine every clocktick */ irqreturn_t timer_interrupt(int irq, void *dummy) { /* Clear the interrupt condition */ outw(0, timer_membase + ALTERA_TIMER_STATUS_REG); nios2_timer_count += NIOS2_TIMER_PERIOD; profile_tick(CPU_PROFILING); xtime_update(1); update_process_times(user_mode(get_irq_regs())); return IRQ_HANDLED; }
irqreturn_t timer_interrupt (int irq, void *dev_id) { unsigned long next; next = get_linux_timer(); again: while ((signed long)(get_ccount() - next) > 0) { profile_tick(CPU_PROFILING); #ifndef CONFIG_SMP update_process_times(user_mode(get_irq_regs())); #endif write_seqlock(&xtime_lock); last_ccount_stamp = next; next += CCOUNT_PER_JIFFY; do_timer (1); /* Linux handler in kernel/timer.c */ if (ntp_synced() && xtime.tv_sec - last_rtc_update >= 659 && abs((xtime.tv_nsec/1000)-(1000000-1000000/HZ))<5000000/HZ) { if (platform_set_rtc_time(xtime.tv_sec+1) == 0) last_rtc_update = xtime.tv_sec+1; else /* Do it again in 60 s */ last_rtc_update += 60; } write_sequnlock(&xtime_lock); } /* NOTE: writing CCOMPAREn clears the interrupt. */ set_linux_timer (next); /* Make sure we didn't miss any tick... */ if ((signed long)(get_ccount() - next) > 0) goto again; /* Allow platform to do something useful (Wdog). */ platform_heartbeat(); return IRQ_HANDLED; }