/** * @ingroup timer * * Initialize the clock and sleep queue. This function is called at startup. */ void clkinit(void) { sleepq = queinit(); /* initialize sleep queue */ clkticks = 0; #ifdef DETAIL kprintf("Time base %dHz, Clock ticks at %dHz\r\n", platform.clkfreq, CLKTICKS_PER_SEC); #endif /* TODO: Get rid of ugly x86 ifdef. */ #ifdef _XINU_PLATFORM_X86_ time_intr_freq = platform.clkfreq / CLKTICKS_PER_SEC; outb(CLOCKCTL, 0x34); /* LSB then MSB */ outb(CLOCKBASE, time_intr_freq); outb(CLOCKBASE, time_intr_freq >> 8); outb(CLOCKBASE, time_intr_freq >> 8); /* why??? */ set_evec(IRQBASE, (ulong)clockIRQ); #else /* register clock interrupt */ interruptVector[IRQ_TIMER] = clkhandler; enable_irq(IRQ_TIMER); clkupdate(platform.clkfreq / CLKTICKS_PER_SEC); #endif }
interrupt clkhandler(void) { /* Reset the timer to fire again */ clkupdate(platform.clkfreq / CLKTICKS_PER_SEC); /* Another clock tick passes. */ clkticks++; /* Update global second counter. */ if (clkticks >= CLKTICKS_PER_SEC) { clktime++; clkticks = 0; } /* If sleepq is not empty, decrement first key. */ /* If key reaches zero, call wakeup. */ if (nonempty(sleepq) && (--firstkey(sleepq) <= 0)) { wakeup(); // This no longer does a resched() call since we need to // clear our interrupts before doing a resched() } #ifdef FLUKE_ARM /* Acknowledge and clear the interrupt */ timer0->int_clr = 1; irq_handled(); #endif resched(); }
/** * Initialize the clock. This function is called at startup. */ void clkinit(void) { #if PREEMPT preempt = QUANTUM; /* initial time quantum */ #endif clkticks = 0; kprintf("Time base %dHz, Clock ticks at %dHz\r\n", platform.clkfreq, CLKTICKS_PER_SEC); /* register clock interrupt */ interruptVector[IRQ_TIMER] = clkhandler; enable_irq(IRQ_TIMER); clkupdate(platform.clkfreq / CLKTICKS_PER_SEC); }
/*------------------------------------------------------------------------ * clkinit - initialize the clock and sleep queue at startup *------------------------------------------------------------------------ */ void clkinit(void) { sleepq = newqueue(); /* allocate a queue to hold the delta */ /* list of sleeping processes */ clkticks = 0; /* start counting one second */ /* Add clock interrupt handler to interrupt vector array */ interruptVector[IRQ_TIMER] = &clkhandler; /* Enable clock interrupts */ enable_irq(IRQ_TIMER); /* Start interval timer */ clkupdate(CLKCYCS_PER_TICK); }
/** * Initialize the clock and sleep queue. This function is called at startup. */ void clkinit(void) { sleepq = queinit(); /* initialize sleep queue */ clkticks = 0; msclkticks = 0; rescheduleMSLeft = RRQUANTUM; #ifdef DETAIL kprintf("Time base %dHz, Clock ticks at %dHz\r\n", platform.clkfreq, CLKTICKS_PER_SEC); #endif /* register clock interrupt */ //timer_init(); register_irq(IRQ_TIMER, clkhandler); enable_irq(IRQ_TIMER); clkupdate(platform.clkfreq / CLKTICKS_PER_SEC); }
interrupt clkhandler(void) { //DEBUG //kprintf("Timer went off\n"); /* Reset the timer to fire again */ clkupdate(platform.clkfreq / CLKTICKS_PER_SEC); /* Another clock tick passes. */ clkticks++; msclkticks++; /* Update global second counter. */ if (clkticks >= CLKTICKS_PER_SEC) { clktime++; clkticks = 0; } /* Update global countdown for round robien reschedule */ if (msclkticks >= (CLKTICKS_PER_SEC/1000)) { rescheduleMSLeft -= 1; msclkticks = 0; } /* If sleepq is not empty, decrement first key. */ /* If key reaches zero, call wakeup. */ if (nonempty(sleepq) && (--firstkey(sleepq) <= 0)) { wakeup(); // This no longer does a resched() call since we need to // clear our interrupts before doing a resched() } /* Acknowledge and clear the interrupt */ timer0->int_clr = 1; irq_handled(); resched(); }