Fixed potential coherency bug in timer code
[tpg/acess2.git] / Kernel / time.c
1 /*
2  * Acess 2
3  * - By John Hodge (thePowersGang) 
4  *
5  * Timer Code
6  */
7 #include <acess.h>
8
9 // === CONSTANTS ===
10 #define NUM_TIMERS      8
11
12 // === TYPEDEFS ===
13 typedef struct sTimer {
14          int    FiresAfter;
15         void    (*Callback)(void*);
16         void    *Argument;
17 } tTimer;
18
19 // === PROTOTYPES ===
20 Sint64  now(void);
21 void    Timer_CallTimers(void);
22
23 // === GLOBALS ===
24 Uint64  giTicks = 0;
25 Sint64  giTimestamp = 0;
26 Uint64  giPartMiliseconds = 0;
27 tTimer  gTimers[NUM_TIMERS];
28
29 // === CODE ===
30 /**
31  * \fn Sint64 now()
32  * \brief Return the current timestamp
33  */
34 Sint64 now(void)
35 {
36         return giTimestamp;
37 }
38
39 /**
40  * \fn void Timer_CallTimers()
41  */
42 void Timer_CallTimers()
43 {
44          int    i;
45         void    (*callback)(void *);
46         void    *arg;
47         
48         for(i = 0;
49                 i < NUM_TIMERS;
50                 i ++)
51         {
52                 if(gTimers[i].Callback == NULL) continue;
53                 if(giTimestamp < gTimers[i].FiresAfter) continue;
54                 callback = gTimers[i].Callback; arg = gTimers[i].Argument;
55                 gTimers[i].Callback = NULL;
56                 callback(arg);
57         }
58 }
59
60 /**
61  * \fn int Time_CreateTimer(int Delta, tTimerCallback *Callback, void *Argument)
62  */
63 int Time_CreateTimer(int Delta, tTimerCallback *Callback, void *Argument)
64 {
65          int    ret;
66         
67         if(Callback == NULL)    return -1;
68         
69         for(ret = 0;
70                 ret < NUM_TIMERS;
71                 ret++)
72         {
73                 if(gTimers[ret].Callback != NULL)       continue;
74                 gTimers[ret].Callback = Callback;
75                 gTimers[ret].FiresAfter = giTimestamp + Delta;
76                 gTimers[ret].Argument = Argument;
77                 //Log("Callback = %p", Callback);
78                 //Log("Timer %i fires at %lli", ret, gTimers[ret].FiresAfter);
79                 return ret;
80         }
81         return -1;
82 }
83
84 /**
85  * \fn void Time_RemoveTimer(int ID)
86  */
87 void Time_RemoveTimer(int ID)
88 {
89         if(ID < 0 || ID >= NUM_TIMERS)  return;
90         gTimers[ID].Callback = NULL;
91 }
92
93 /**
94  * \fn void Time_Delay(int Delay)
95  * \brief Delay for a small ammount of time
96  */
97 void Time_Delay(int Delay)
98 {
99         Sint64  dest = giTimestamp + Delay;
100         while(dest < giTimestamp)       Threads_Yield();
101 }
102
103 // === EXPORTS ===
104 EXPORT(now);
105 EXPORT(Time_CreateTimer);
106 EXPORT(Time_RemoveTimer);
107 EXPORT(Time_Delay);

UCC git Repository :: git.ucc.asn.au