/* * timer0 clock interrupt. Timer0 is in one-shot mode and has stopped * counting as of this interrupt. We use timer1 in free-running mode (not * generating any interrupts) as our main counter. Each cpu has timeouts * pending. * * This code is INTR_MPSAFE and may be called without the BGL held. */ static void clkintr(void *dummy, void *frame_arg) { static sysclock_t sysclock_count; /* NOTE! Must be static */ struct globaldata *gd = mycpu; struct globaldata *gscan; int n; /* * SWSTROBE mode is a one-shot, the timer is no longer running */ timer0_running = 0; /* * XXX the dispatcher needs work. right now we call systimer_intr() * directly or via IPI for any cpu with systimers queued, which is * usually *ALL* of them. We need to use the LAPIC timer for this. */ sysclock_count = sys_cputimer->count(); for (n = 0; n < ncpus; ++n) { gscan = globaldata_find(n); if (TAILQ_FIRST(&gscan->gd_systimerq) == NULL) continue; if (gscan != gd) { lwkt_send_ipiq3(gscan, (ipifunc3_t)systimer_intr, &sysclock_count, 1); } else { systimer_intr(&sysclock_count, 0, frame_arg); } } }
static void lapic_timer_process_oncpu(struct globaldata *gd, struct intrframe *frame) { sysclock_t count; gd->gd_timer_running = 0; count = sys_cputimer->count(); if (TAILQ_FIRST(&gd->gd_systimerq) != NULL) systimer_intr(&count, 0, frame); }