Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentime.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS NDIS library 00004 * FILE: ndis/time.c 00005 * PURPOSE: Time related routines 00006 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) 00007 * Vizzini (vizzini@plasmic.com) 00008 * REVISIONS: 00009 * CSH 01/08-2000 Created 00010 * Vizzini 08-Oct-2003 Formatting, commenting, and ASSERTs 00011 * 00012 * NOTES: 00013 * - Although the standard kernel-mode M.O. is to trust the caller 00014 * to not provide bad arguments, we have added lots of argument 00015 * validation to assist in the effort to get third-party binaries 00016 * working. It is easiest to track bugs when things break quickly 00017 * and badly. 00018 */ 00019 00020 #include "ndissys.h" 00021 00022 00023 /* 00024 * @implemented 00025 */ 00026 VOID 00027 EXPORT 00028 NdisCancelTimer( 00029 IN PNDIS_TIMER Timer, 00030 OUT PBOOLEAN TimerCancelled) 00031 /* 00032 * FUNCTION: Cancels a scheduled NDIS timer 00033 * ARGUMENTS: 00034 * Timer: pointer to an NDIS_TIMER object to cancel 00035 * TimerCancelled: boolean that returns cancellation status 00036 * NOTES: 00037 * - call at IRQL <= DISPATCH_LEVEL 00038 */ 00039 { 00040 ASSERT_IRQL(DISPATCH_LEVEL); 00041 ASSERT(Timer); 00042 00043 *TimerCancelled = KeCancelTimer (&Timer->Timer); 00044 } 00045 00046 00047 /* 00048 * @implemented 00049 */ 00050 #undef NdisGetCurrentSystemTime 00051 VOID 00052 EXPORT 00053 NdisGetCurrentSystemTime ( 00054 IN OUT PLARGE_INTEGER pSystemTime) 00055 /* 00056 * FUNCTION: Retrieve the current system time 00057 * ARGUMENTS: 00058 * pSystemTime: pointer to the returned system time 00059 * NOTES: 00060 * - call at any IRQL 00061 */ 00062 { 00063 ASSERT(pSystemTime); 00064 00065 KeQuerySystemTime (pSystemTime); 00066 } 00067 00068 00069 /* 00070 * @implemented 00071 */ 00072 VOID 00073 EXPORT 00074 NdisInitializeTimer( 00075 IN OUT PNDIS_TIMER Timer, 00076 IN PNDIS_TIMER_FUNCTION TimerFunction, 00077 IN PVOID FunctionContext) 00078 /* 00079 * FUNCTION: Set up an NDIS_TIMER for later use 00080 * ARGUMENTS: 00081 * Timer: pointer to caller-allocated storage to receive an NDIS_TIMER 00082 * TimerFunction: function pointer to routine to run when timer expires 00083 * FunctionContext: context (param 2) to be passed to the timer function when it runs 00084 * NOTES: 00085 * - TimerFunction will be called at DISPATCH_LEVEL 00086 * - call at IRQL = PASSIVE_LEVEL 00087 */ 00088 { 00089 PAGED_CODE(); 00090 ASSERT(Timer); 00091 00092 KeInitializeTimer (&Timer->Timer); 00093 00094 KeInitializeDpc (&Timer->Dpc, (PKDEFERRED_ROUTINE)TimerFunction, FunctionContext); 00095 } 00096 00097 BOOLEAN DequeueMiniportTimer(PNDIS_MINIPORT_TIMER Timer) 00098 { 00099 PNDIS_MINIPORT_TIMER CurrentTimer; 00100 00101 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); 00102 00103 if (!Timer->Miniport->TimerQueue) 00104 return FALSE; 00105 00106 if (Timer->Miniport->TimerQueue == Timer) 00107 { 00108 Timer->Miniport->TimerQueue = Timer->NextDeferredTimer; 00109 Timer->NextDeferredTimer = NULL; 00110 return TRUE; 00111 } 00112 else 00113 { 00114 CurrentTimer = Timer->Miniport->TimerQueue; 00115 while (CurrentTimer->NextDeferredTimer) 00116 { 00117 if (CurrentTimer->NextDeferredTimer == Timer) 00118 { 00119 CurrentTimer->NextDeferredTimer = Timer->NextDeferredTimer; 00120 Timer->NextDeferredTimer = NULL; 00121 return TRUE; 00122 } 00123 CurrentTimer = CurrentTimer->NextDeferredTimer; 00124 } 00125 return FALSE; 00126 } 00127 } 00128 00129 00130 /* 00131 * @implemented 00132 */ 00133 VOID 00134 EXPORT 00135 NdisMCancelTimer( 00136 IN PNDIS_MINIPORT_TIMER Timer, 00137 OUT PBOOLEAN TimerCancelled) 00138 /* 00139 * FUNCTION: cancel a scheduled NDIS_MINIPORT_TIMER 00140 * ARGUMENTS: 00141 * Timer: timer object to cancel 00142 * TimerCancelled: status of cancel operation 00143 * NOTES: 00144 * - call at IRQL <= DISPATCH_LEVEL 00145 */ 00146 { 00147 //KIRQL OldIrql; 00148 00149 ASSERT_IRQL(DISPATCH_LEVEL); 00150 ASSERT(TimerCancelled); 00151 ASSERT(Timer); 00152 00153 *TimerCancelled = KeCancelTimer (&Timer->Timer); 00154 00155 #if 0 00156 if (*TimerCancelled) 00157 { 00158 KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql); 00159 /* If it's somebody already dequeued it, something is wrong (maybe a double-cancel?) */ 00160 if (!DequeueMiniportTimer(Timer)) ASSERT(FALSE); 00161 KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql); 00162 } 00163 #endif 00164 } 00165 00166 VOID NTAPI 00167 MiniTimerDpcFunction(PKDPC Dpc, 00168 PVOID DeferredContext, 00169 PVOID SystemArgument1, 00170 PVOID SystemArgument2) 00171 { 00172 PNDIS_MINIPORT_TIMER Timer = DeferredContext; 00173 00174 #if 0 00175 /* Only dequeue if the timer has a period of 0 */ 00176 if (!Timer->Timer.Period) 00177 { 00178 KeAcquireSpinLockAtDpcLevel(&Timer->Miniport->Lock); 00179 /* If someone already dequeued it, something is wrong (borked timer implementation?) */ 00180 if (!DequeueMiniportTimer(Timer)) ASSERT(FALSE); 00181 KeReleaseSpinLockFromDpcLevel(&Timer->Miniport->Lock); 00182 } 00183 #endif 00184 00185 Timer->MiniportTimerFunction(Dpc, 00186 Timer->MiniportTimerContext, 00187 SystemArgument1, 00188 SystemArgument2); 00189 } 00190 00191 00192 /* 00193 * @implemented 00194 */ 00195 VOID 00196 EXPORT 00197 NdisMInitializeTimer( 00198 IN OUT PNDIS_MINIPORT_TIMER Timer, 00199 IN NDIS_HANDLE MiniportAdapterHandle, 00200 IN PNDIS_TIMER_FUNCTION TimerFunction, 00201 IN PVOID FunctionContext) 00202 /* 00203 * FUNCTION: Initialize an NDIS_MINIPORT_TIMER 00204 * ARGUMENTS: 00205 * Timer: Timer object to initialize 00206 * MiniportAdapterHandle: Handle to the miniport, passed in to MiniportInitialize 00207 * TimerFunction: function to be executed when the timer expires 00208 * FunctionContext: argument passed to TimerFunction when it is called 00209 * NOTES: 00210 * - TimerFunction is called at IRQL = DISPATCH_LEVEL 00211 * - call at IRQL = PASSIVE_LEVEL 00212 */ 00213 { 00214 PAGED_CODE(); 00215 ASSERT(Timer); 00216 00217 KeInitializeTimer (&Timer->Timer); 00218 KeInitializeDpc (&Timer->Dpc, MiniTimerDpcFunction, Timer); 00219 00220 Timer->MiniportTimerFunction = TimerFunction; 00221 Timer->MiniportTimerContext = FunctionContext; 00222 Timer->Miniport = &((PLOGICAL_ADAPTER)MiniportAdapterHandle)->NdisMiniportBlock; 00223 Timer->NextDeferredTimer = NULL; 00224 } 00225 00226 00227 /* 00228 * @implemented 00229 */ 00230 VOID 00231 EXPORT 00232 NdisMSetPeriodicTimer( 00233 IN PNDIS_MINIPORT_TIMER Timer, 00234 IN UINT MillisecondsPeriod) 00235 /* 00236 * FUNCTION: Set a timer to go off periodically 00237 * ARGUMENTS: 00238 * Timer: pointer to the timer object to set 00239 * MillisecondsPeriod: period of the timer 00240 * NOTES: 00241 * - Minimum predictible interval is ~10ms 00242 * - Must be called at IRQL <= DISPATCH_LEVEL 00243 */ 00244 { 00245 LARGE_INTEGER Timeout; 00246 //KIRQL OldIrql; 00247 00248 ASSERT_IRQL(DISPATCH_LEVEL); 00249 ASSERT(Timer); 00250 00251 /* relative delays are negative, absolute are positive; resolution is 100ns */ 00252 Timeout.QuadPart = Int32x32To64(MillisecondsPeriod, -10000); 00253 00254 #if 0 00255 /* Lock the miniport block */ 00256 KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql); 00257 00258 /* Attempt to dequeue the timer */ 00259 DequeueMiniportTimer(Timer); 00260 00261 /* Add the timer at the head of the timer queue */ 00262 Timer->NextDeferredTimer = Timer->Miniport->TimerQueue; 00263 Timer->Miniport->TimerQueue = Timer; 00264 00265 /* Unlock the miniport block */ 00266 KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql); 00267 #endif 00268 00269 KeSetTimerEx(&Timer->Timer, Timeout, MillisecondsPeriod, &Timer->Dpc); 00270 } 00271 00272 00273 /* 00274 * @implemented 00275 */ 00276 #undef NdisMSetTimer 00277 VOID 00278 EXPORT 00279 NdisMSetTimer( 00280 IN PNDIS_MINIPORT_TIMER Timer, 00281 IN UINT MillisecondsToDelay) 00282 /* 00283 * FUNCTION: Set a NDIS_MINIPORT_TIMER so that it goes off 00284 * ARGUMENTS: 00285 * Timer: timer object to set 00286 * MillisecondsToDelay: time to wait for the timer to expire 00287 * NOTES: 00288 * - Minimum predictible interval is ~10ms 00289 * - Must be called at IRQL <= DISPATCH_LEVEL 00290 */ 00291 { 00292 LARGE_INTEGER Timeout; 00293 //KIRQL OldIrql; 00294 00295 ASSERT_IRQL(DISPATCH_LEVEL); 00296 ASSERT(Timer); 00297 00298 /* relative delays are negative, absolute are positive; resolution is 100ns */ 00299 Timeout.QuadPart = Int32x32To64(MillisecondsToDelay, -10000); 00300 00301 #if 0 00302 /* Lock the miniport block */ 00303 KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql); 00304 00305 /* Attempt to dequeue the timer */ 00306 DequeueMiniportTimer(Timer); 00307 00308 /* Add the timer at the head of the timer queue */ 00309 Timer->NextDeferredTimer = Timer->Miniport->TimerQueue; 00310 Timer->Miniport->TimerQueue = Timer; 00311 00312 /* Unlock the miniport block */ 00313 KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql); 00314 #endif 00315 00316 KeSetTimer(&Timer->Timer, Timeout, &Timer->Dpc); 00317 } 00318 00319 00320 /* 00321 * @implemented 00322 */ 00323 VOID 00324 EXPORT 00325 NdisSetTimer( 00326 IN PNDIS_TIMER Timer, 00327 IN UINT MillisecondsToDelay) 00328 /* 00329 * FUNCTION: Set an NDIS_TIMER so that it goes off 00330 * ARGUMENTS: 00331 * Timer: timer object to set 00332 * MillisecondsToDelay: time to wait for the timer to expire 00333 * NOTES: 00334 * - Minimum predictible interval is ~10ms 00335 * - Must be called at IRQL <= DISPATCH_LEVEL 00336 */ 00337 { 00338 LARGE_INTEGER Timeout; 00339 00340 ASSERT_IRQL(DISPATCH_LEVEL); 00341 ASSERT(Timer); 00342 00343 NDIS_DbgPrint(MAX_TRACE, ("Called. Timer is: 0x%x, Timeout is: %ld\n", Timer, MillisecondsToDelay)); 00344 00345 /* relative delays are negative, absolute are positive; resolution is 100ns */ 00346 Timeout.QuadPart = Int32x32To64(MillisecondsToDelay, -10000); 00347 00348 KeSetTimer (&Timer->Timer, Timeout, &Timer->Dpc); 00349 } 00350 00351 /* 00352 * @implemented 00353 */ 00354 VOID 00355 EXPORT 00356 NdisSetTimerEx( 00357 IN PNDIS_TIMER Timer, 00358 IN UINT MillisecondsToDelay, 00359 IN PVOID FunctionContext) 00360 { 00361 NDIS_DbgPrint(MAX_TRACE, ("Called. Timer is: 0x%x, Timeout is: %ld, FunctionContext is: 0x%x\n", 00362 Timer, MillisecondsToDelay, FunctionContext)); 00363 00364 Timer->Dpc.DeferredContext = FunctionContext; 00365 00366 NdisSetTimer(Timer, MillisecondsToDelay); 00367 } 00368 00369 /* EOF */ 00370 Generated on Sun May 27 2012 04:18:16 for ReactOS by
1.7.6.1
|