X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=blobdiff_plain;f=palacios%2Fsrc%2Fgeekos%2Ftimer.c;h=f9139bc10ea4e413ffec83c35b6a6f4303d93604;hp=01b716d235a62f49d178746836f1fd48071d82b0;hb=eb7dda8d4a92a2e8d0c8f867c65317d756ca6c11;hpb=a1e11b02345601df1b136787ccbdb213c77bea32 diff --git a/palacios/src/geekos/timer.c b/palacios/src/geekos/timer.c index 01b716d..f9139bc 100644 --- a/palacios/src/geekos/timer.c +++ b/palacios/src/geekos/timer.c @@ -2,7 +2,7 @@ * GeekOS timer interrupt support * Copyright (c) 2001,2003 David H. Hovemeyer * Copyright (c) 2003, Jeffrey K. Hollingsworth - * $Revision: 1.10 $ + * $Revision: 1.11 $ * * This is free software. You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". @@ -18,6 +18,7 @@ #include #include +#include /* PAD this currently is in nvram.c */ extern void deliver_timer_interrupt_to_vmm(uint_t period_us); @@ -26,53 +27,10 @@ extern void deliver_timer_interrupt_to_vmm(uint_t period_us); uint_t cpu_khz_freq; -#define __SLOW_DOWN_IO "\noutb %%al,$0x80" -#ifdef REALLY_SLOW_IO -#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO -#else -#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO -#endif - - - -#define __OUT1(s,x) \ -static inline void out##s(unsigned x value, unsigned short port) { - -#define __OUT2(s,s1,s2) \ -__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1" - -#define __OUT(s,s1,x) \ -__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \ -__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \ - - -#define __IN1(s) \ -static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v; - -#define __IN2(s,s1,s2) \ -__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0" - -#define __IN(s,s1,i...) \ -__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \ -__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \ - - -#define RETURN_TYPE unsigned char -__IN(b,"") -#undef RETURN_TYPE -#define RETURN_TYPE unsigned short -__IN(w,"") -#undef RETURN_TYPE -#define RETURN_TYPE unsigned int -__IN(l,"") -#undef RETURN_TYPE -__OUT(b,"b",char) -__OUT(w,"w",short) - @@ -157,6 +115,13 @@ pit_calibrate_tsc(void) +#define MAX_TIMER_EVENTS 100 + +static int timerDebug = 0; +static int timeEventCount; +static int nextEventID; +timerEvent pendingTimerEvents[MAX_TIMER_EVENTS]; + /* @@ -210,39 +175,50 @@ int g_Quantum = DEFAULT_MAX_TICKS; static void Timer_Interrupt_Handler(struct Interrupt_State* state) { - struct Kernel_Thread* current = g_currentThread; - - Begin_IRQ(state); - - + int i; + struct Kernel_Thread* current = g_currentThread; -#if 0 -#define STACK_LEN 256 + Begin_IRQ(state); - SerialPrint("Host Timer Interrupt Handler running\n"); - SerialPrint("Timer====\n"); - Dump_Interrupt_State(state); - // SerialMemDump((unsigned char*)(¤t),STACK_LEN); - SerialPrint("Timer done===\n"); - -#endif - /* Update global and per-thread number of ticks */ - ++g_numTicks; - ++current->numTicks; + /* Update global and per-thread number of ticks */ + ++g_numTicks; + ++current->numTicks; + + /* update timer events */ + for (i=0; i < timeEventCount; i++) { + if (pendingTimerEvents[i].ticks == 0) { + if (timerDebug) Print("timer: event %d expired (%d ticks)\n", + pendingTimerEvents[i].id, pendingTimerEvents[i].origTicks); + (pendingTimerEvents[i].callBack)(pendingTimerEvents[i].id); + pendingTimerEvents[i].ticks = pendingTimerEvents[i].origTicks; + } else { + pendingTimerEvents[i].ticks--; + } + } + + /* + * If thread has been running for an entire quantum, + * inform the interrupt return code that we want + * to choose a new thread. + */ + if (current->numTicks >= g_Quantum) { + g_needReschedule = true; /* - * If thread has been running for an entire quantum, - * inform the interrupt return code that we want - * to choose a new thread. + * The current process is moved to a lower priority queue, + * since it consumed a full quantum. */ - if (current->numTicks >= g_Quantum) { - g_needReschedule = true; - } - - - deliver_timer_interrupt_to_vmm(1000000/HZ); - - End_IRQ(state); + //if (current->currentReadyQueue < (MAX_QUEUE_LEVEL - 1)) { + /*Print("process %d moved to ready queue %d\n", current->pid, current->currentReadyQueue); */ + //current->currentReadyQueue++; + //} + + } + + + deliver_timer_interrupt_to_vmm(1000000/HZ); + + End_IRQ(state); } /* @@ -360,6 +336,57 @@ void Init_Timer(void) } +int Start_Timer(int ticks, timerCallback cb) +{ + int ret; + + KASSERT(!Interrupts_Enabled()); + + if (timeEventCount == MAX_TIMER_EVENTS) { + return -1; + } else { + ret = nextEventID++; + pendingTimerEvents[timeEventCount].id = ret; + pendingTimerEvents[timeEventCount].callBack = cb; + pendingTimerEvents[timeEventCount].ticks = ticks; + pendingTimerEvents[timeEventCount].origTicks = ticks; + timeEventCount++; + + return ret; + } +} + +int Get_Remaing_Timer_Ticks(int id) +{ + int i; + + KASSERT(!Interrupts_Enabled()); + for (i=0; i < timeEventCount; i++) { + if (pendingTimerEvents[i].id == id) { + return pendingTimerEvents[i].ticks; + } + } + + return -1; +} + +int Cancel_Timer(int id) +{ + int i; + KASSERT(!Interrupts_Enabled()); + for (i=0; i < timeEventCount; i++) { + if (pendingTimerEvents[i].id == id) { + pendingTimerEvents[i] = pendingTimerEvents[timeEventCount-1]; + timeEventCount--; + return 0; + } + } + + Print("timer: unable to find timer id %d to cancel it\n", id); + return -1; +} + + #define US_PER_TICK (HZ * 1000000) /*