X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Ftime.c;h=f7d02cc10d3f32b1ac5396a7962156b30487f7d6;hb=9d3800f60f2212432e550a4e003ae65b498a4d36;hp=3a13904f819d0776793194cee9f37f7c474166de;hpb=8bc40333b1401d7616b225945fee53d972c2f418;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/time.c b/Kernel/arch/x86/time.c index 3a13904f..f7d02cc1 100644 --- a/Kernel/arch/x86/time.c +++ b/Kernel/arch/x86/time.c @@ -6,17 +6,28 @@ #include // === MACROS === +#define NUM_TIMERS 8 +#define TIMER_QUANTUM 100 #define TIMER_FREQ 1024 //Hz #define MS_PER_TICK_WHOLE (1000/(TIMER_FREQ)) #define MS_PER_TICK_FRACT ((Uint64)(1000*TIMER_FREQ-((Uint64)MS_PER_TICK_WHOLE)*0x80000000/TIMER_FREQ)) +// === TYPEDEFS === +typedef struct sTimer { + int FiresAfter; + void (*Callback)(void*); + void *Argument; +} tTimer; + // === PROTOTYPES === void Time_Interrupt(); +void Timer_CallTimers(); // === GLOBALS === Uint64 giTicks = 0; Sint64 giTimestamp = 0; Uint64 giPartMiliseconds = 0; +tTimer gTimers[NUM_TIMERS]; // === CODE === /** @@ -57,7 +68,28 @@ void Time_Interrupt() giTimestamp ++; giPartMiliseconds -= 0x80000000; } + + Timer_CallTimers(); +} + +/** + * \fn void Time_TimerThread() + */ +#if 0 +void Time_TimerThread() +{ + Sint64 next; + Threads_SetName("TIMER"); + + next = giTimestamp + TIMER_QUANTUM; + for(;;) + { + while(giTimestamp < next) Threads_Yield(); + next = giTimestamp + TIMER_QUANTUM; + Timer_CallTimers(); + } } +#endif /** * \fn Sint64 now() @@ -67,3 +99,61 @@ Sint64 now() { return giTimestamp; } + +/** + * \fn void Timer_CallTimers() + */ +void Timer_CallTimers() +{ + int i; + void (*callback)(void *); + + for(i = 0; + i < NUM_TIMERS; + i ++) + { + if(gTimers[i].Callback == NULL) continue; + if(giTimestamp < gTimers[i].FiresAfter) continue; + callback = gTimers[i].Callback; + gTimers[i].Callback = NULL; + callback(gTimers[i].Argument); + } +} + +/** + * \fn int Time_CreateTimer(int Delta, void *Callback, void *Argument) + */ +int Time_CreateTimer(int Delta, void *Callback, void *Argument) +{ + int ret; + for(ret = 0; + ret < NUM_TIMERS; + ret++) + { + if(gTimers[ret].Callback != NULL) continue; + gTimers[ret].Callback = Callback; + gTimers[ret].FiresAfter = giTimestamp + Delta; + gTimers[ret].Argument = Argument; + return ret; + } + return -1; +} + +/** + * \fn void Time_RemoveTimer(int ID) + */ +void Time_RemoveTimer(int ID) +{ + if(ID < 0 || ID >= NUM_TIMERS) return; + gTimers[ID].Callback = NULL; +} + +/** + * \fn void Time_Delay(int Delay) + * \brief Delay for a small ammount of time + */ +void Time_Delay(int Delay) +{ + Sint64 dest = giTimestamp + Delay; + while(dest < giTimestamp) Threads_Yield(); +}