]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Dxe/Event/Timer.c
Update to fix minor coding style issues.
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Event / Timer.c
CommitLineData
23c98c94 1/** @file\r
504214c4
LG
2 Core Timer Services\r
3\r
23c98c94 4Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
28a00297 5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
504214c4 13**/\r
28a00297 14\r
15\r
16#include <DxeMain.h>\r
17\r
18//\r
19// Internal prototypes\r
20//\r
162ed594 21/**\r
22 Returns the current system time.\r
23\r
24 @return The current system time\r
25\r
26**/\r
28a00297 27UINT64\r
28CoreCurrentSystemTime (\r
29 VOID\r
30 );\r
31\r
162ed594 32/**\r
33 Checks the sorted timer list against the current system time.\r
34 Signals any expired event timer.\r
35\r
36 @param CheckEvent Not used \r
37 @param Context Not used\r
38\r
39**/\r
28a00297 40VOID\r
41EFIAPI\r
42CoreCheckTimers (\r
23c98c94 43 IN EFI_EVENT CheckEvent,\r
44 IN VOID *Context\r
28a00297 45 );\r
46\r
162ed594 47/**\r
48 Inserts the timer event.\r
49\r
50 @param Event Points to the internal structure of timer event \r
51 to be installed\r
52\r
53**/\r
28a00297 54VOID\r
55CoreInsertEventTimer (\r
23c98c94 56 IN IEVENT *Event\r
28a00297 57 );\r
58\r
59//\r
60// Internal data\r
61//\r
62\r
db405d1b 63STATIC LIST_ENTRY mEfiTimerList = INITIALIZE_LIST_HEAD_VARIABLE (mEfiTimerList);\r
64STATIC EFI_LOCK mEfiTimerLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL - 1);\r
65STATIC EFI_EVENT mEfiCheckTimerEvent;\r
28a00297 66\r
db405d1b 67STATIC EFI_LOCK mEfiSystemTimeLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL);\r
68STATIC UINT64 mEfiSystemTime = 0;\r
28a00297 69\r
70//\r
71// Timer functions\r
72//\r
73\r
162ed594 74\r
75/**\r
76 Initializes timer support.\r
77\r
78**/\r
28a00297 79VOID\r
80CoreInitializeTimer (\r
81 VOID\r
82 )\r
28a00297 83{\r
84 EFI_STATUS Status;\r
85\r
86 Status = CoreCreateEvent (\r
87 EVT_NOTIFY_SIGNAL,\r
88 TPL_HIGH_LEVEL - 1,\r
89 CoreCheckTimers,\r
90 NULL,\r
91 &mEfiCheckTimerEvent\r
92 );\r
93 ASSERT_EFI_ERROR (Status);\r
94}\r
95\r
162ed594 96\r
97/**\r
98 Returns the current system time.\r
99\r
100 @return The current system time\r
101\r
102**/\r
28a00297 103UINT64\r
104CoreCurrentSystemTime (\r
105 VOID\r
106 )\r
28a00297 107{\r
108 UINT64 SystemTime;\r
109\r
110 CoreAcquireLock (&mEfiSystemTimeLock);\r
111 SystemTime = mEfiSystemTime;\r
112 CoreReleaseLock (&mEfiSystemTimeLock);\r
113 return SystemTime;\r
114}\r
115\r
162ed594 116\r
117/**\r
118 Called by the platform code to process a tick.\r
119\r
120 @param Duration The number of 100ns elasped since the last call \r
121 to TimerTick\r
122\r
123**/\r
28a00297 124VOID\r
125EFIAPI\r
126CoreTimerTick (\r
127 IN UINT64 Duration\r
128 )\r
28a00297 129{\r
130 IEVENT *Event;\r
131\r
132 //\r
133 // Check runtiem flag in case there are ticks while exiting boot services\r
134 //\r
135\r
136 CoreAcquireLock (&mEfiSystemTimeLock);\r
137\r
138 //\r
139 // Update the system time\r
140 //\r
141\r
142 mEfiSystemTime += Duration;\r
143\r
144 //\r
145 // If the head of the list is expired, fire the timer event\r
146 // to process it\r
147 //\r
148\r
149 if (!IsListEmpty (&mEfiTimerList)) {\r
150 Event = CR (mEfiTimerList.ForwardLink, IEVENT, u.Timer.Link, EVENT_SIGNATURE);\r
151\r
152 if (Event->u.Timer.TriggerTime <= mEfiSystemTime) {\r
153 CoreSignalEvent (mEfiCheckTimerEvent);\r
154 }\r
155 }\r
156\r
157 CoreReleaseLock (&mEfiSystemTimeLock);\r
158}\r
159\r
162ed594 160\r
161/**\r
162 Checks the sorted timer list against the current system time.\r
163 Signals any expired event timer.\r
164\r
165 @param CheckEvent Not used \r
166 @param Context Not used\r
167\r
168**/\r
28a00297 169VOID\r
170EFIAPI\r
171CoreCheckTimers (\r
172 IN EFI_EVENT CheckEvent,\r
173 IN VOID *Context\r
174 )\r
28a00297 175{\r
176 UINT64 SystemTime;\r
177 IEVENT *Event;\r
178\r
179 //\r
180 // Check the timer database for expired timers\r
181 //\r
182\r
183 CoreAcquireLock (&mEfiTimerLock);\r
184 SystemTime = CoreCurrentSystemTime ();\r
185\r
186 while (!IsListEmpty (&mEfiTimerList)) {\r
187 Event = CR (mEfiTimerList.ForwardLink, IEVENT, u.Timer.Link, EVENT_SIGNATURE);\r
188\r
189 //\r
190 // If this timer is not expired, then we're done\r
191 //\r
192\r
193 if (Event->u.Timer.TriggerTime > SystemTime) {\r
194 break;\r
195 }\r
196\r
197 //\r
198 // Remove this timer from the timer queue\r
199 //\r
200\r
201 RemoveEntryList (&Event->u.Timer.Link);\r
202 Event->u.Timer.Link.ForwardLink = NULL;\r
203\r
204 //\r
205 // Signal it\r
206 //\r
207 CoreSignalEvent (Event);\r
208\r
209 //\r
210 // If this is a periodic timer, set it\r
211 //\r
212 if (Event->u.Timer.Period) {\r
213\r
214 //\r
215 // Compute the timers new trigger time\r
216 //\r
217\r
218 Event->u.Timer.TriggerTime = Event->u.Timer.TriggerTime + Event->u.Timer.Period;\r
219\r
220 //\r
221 // If that's before now, then reset the timer to start from now\r
222 //\r
223 if (Event->u.Timer.TriggerTime <= SystemTime) {\r
224 Event->u.Timer.TriggerTime = SystemTime;\r
225 CoreSignalEvent (mEfiCheckTimerEvent);\r
226 }\r
227\r
228 //\r
229 // Add the timer\r
230 //\r
231\r
232 CoreInsertEventTimer (Event);\r
233 }\r
234 }\r
235\r
236 CoreReleaseLock (&mEfiTimerLock);\r
237}\r
238\r
162ed594 239\r
240/**\r
241 Inserts the timer event.\r
242\r
243 @param Event Points to the internal structure of timer event \r
244 to be installed\r
245\r
246**/\r
28a00297 247VOID\r
248CoreInsertEventTimer (\r
249 IN IEVENT *Event\r
250 )\r
28a00297 251{\r
252 UINT64 TriggerTime;\r
253 LIST_ENTRY *Link;\r
254 IEVENT *Event2;\r
255\r
256 ASSERT_LOCKED (&mEfiTimerLock);\r
257\r
258 //\r
259 // Get the timer's trigger time\r
260 //\r
261\r
262 TriggerTime = Event->u.Timer.TriggerTime;\r
263\r
264 //\r
265 // Insert the timer into the timer database in assending sorted order\r
266 //\r
267\r
268 for (Link = mEfiTimerList.ForwardLink; Link != &mEfiTimerList; Link = Link->ForwardLink) {\r
269 Event2 = CR (Link, IEVENT, u.Timer.Link, EVENT_SIGNATURE);\r
270\r
271 if (Event2->u.Timer.TriggerTime > TriggerTime) {\r
272 break;\r
273 }\r
274 }\r
275\r
276 InsertTailList (Link, &Event->u.Timer.Link);\r
277}\r
278\r
279\r
280\r
162ed594 281\r
282/**\r
283 Sets the type of timer and the trigger time for a timer event.\r
284\r
285 @param UserEvent The timer event that is to be signaled at the \r
286 specified time \r
287 @param Type The type of time that is specified in \r
288 TriggerTime \r
289 @param TriggerTime The number of 100ns units until the timer \r
290 expires \r
291\r
292 @retval EFI_SUCCESS The event has been set to be signaled at the \r
293 requested time \r
294 @retval EFI_INVALID_PARAMETER Event or Type is not valid\r
295\r
296**/\r
28a00297 297EFI_STATUS\r
298EFIAPI\r
299CoreSetTimer (\r
300 IN EFI_EVENT UserEvent,\r
301 IN EFI_TIMER_DELAY Type,\r
302 IN UINT64 TriggerTime\r
303 )\r
28a00297 304{\r
305 IEVENT *Event;\r
306\r
307 Event = UserEvent;\r
308\r
309 if (Event == NULL) {\r
310 return EFI_INVALID_PARAMETER;\r
311 }\r
312\r
313 if (Event->Signature != EVENT_SIGNATURE) {\r
314 return EFI_INVALID_PARAMETER;\r
315 }\r
316\r
317 if (Type < 0 || Type > TimerRelative || !(Event->Type & EVT_TIMER)) {\r
318 return EFI_INVALID_PARAMETER;\r
319 }\r
320\r
321 CoreAcquireLock (&mEfiTimerLock);\r
322\r
323 //\r
324 // If the timer is queued to the timer database, remove it\r
325 //\r
326\r
327 if (Event->u.Timer.Link.ForwardLink != NULL) {\r
328 RemoveEntryList (&Event->u.Timer.Link);\r
329 Event->u.Timer.Link.ForwardLink = NULL;\r
330 }\r
331\r
332 Event->u.Timer.TriggerTime = 0;\r
333 Event->u.Timer.Period = 0;\r
334\r
335 if (Type != TimerCancel) {\r
336\r
337 if (Type == TimerPeriodic) {\r
338 Event->u.Timer.Period = TriggerTime;\r
339 }\r
340\r
341 Event->u.Timer.TriggerTime = CoreCurrentSystemTime () + TriggerTime;\r
342 CoreInsertEventTimer (Event);\r
343\r
344 if (TriggerTime == 0) {\r
345 CoreSignalEvent (mEfiCheckTimerEvent);\r
346 }\r
347 }\r
348\r
349 CoreReleaseLock (&mEfiTimerLock);\r
350 return EFI_SUCCESS;\r
351}\r