ReactOS  0.4.14-dev-358-gbef841c
time.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS NDIS library
4  * FILE: ndis/time.c
5  * PURPOSE: Time related routines
6  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7  * Vizzini (vizzini@plasmic.com)
8  * REVISIONS:
9  * CSH 01/08-2000 Created
10  * Vizzini 08-Oct-2003 Formatting, commenting, and ASSERTs
11  *
12  * NOTES:
13  * - Although the standard kernel-mode M.O. is to trust the caller
14  * to not provide bad arguments, we have added lots of argument
15  * validation to assist in the effort to get third-party binaries
16  * working. It is easiest to track bugs when things break quickly
17  * and badly.
18  */
19 
20 #include "ndissys.h"
21 
22 /*
23  * @implemented
24  */
25 VOID
26 EXPORT
30 /*
31  * FUNCTION: Cancels a scheduled NDIS timer
32  * ARGUMENTS:
33  * Timer: pointer to an NDIS_TIMER object to cancel
34  * TimerCancelled: boolean that returns cancellation status
35  * NOTES:
36  * - call at IRQL <= DISPATCH_LEVEL
37  */
38 {
40  ASSERT(Timer);
41 
43 }
44 
45 /*
46  * @implemented
47  */
48 #undef NdisGetCurrentSystemTime
49 VOID
50 EXPORT
52  IN OUT PLARGE_INTEGER pSystemTime)
53 /*
54  * FUNCTION: Retrieve the current system time
55  * ARGUMENTS:
56  * pSystemTime: pointer to the returned system time
57  * NOTES:
58  * - call at any IRQL
59  */
60 {
61  ASSERT(pSystemTime);
62 
63  KeQuerySystemTime (pSystemTime);
64 }
65 
66 /*
67  * @implemented
68  */
69 VOID
70 EXPORT
75 /*
76  * FUNCTION: Set up an NDIS_TIMER for later use
77  * ARGUMENTS:
78  * Timer: pointer to caller-allocated storage to receive an NDIS_TIMER
79  * TimerFunction: function pointer to routine to run when timer expires
80  * FunctionContext: context (param 2) to be passed to the timer function when it runs
81  * NOTES:
82  * - TimerFunction will be called at DISPATCH_LEVEL
83  * - call at IRQL = PASSIVE_LEVEL
84  */
85 {
86  PAGED_CODE();
87  ASSERT(Timer);
88 
90 
92 }
93 
95 {
96  PNDIS_MINIPORT_TIMER CurrentTimer;
97 
99 
100  if (!Timer->Miniport->TimerQueue)
101  return FALSE;
102 
103  if (Timer->Miniport->TimerQueue == Timer)
104  {
105  Timer->Miniport->TimerQueue = Timer->NextDeferredTimer;
106  Timer->NextDeferredTimer = NULL;
107  return TRUE;
108  }
109  else
110  {
111  CurrentTimer = Timer->Miniport->TimerQueue;
112  while (CurrentTimer->NextDeferredTimer)
113  {
114  if (CurrentTimer->NextDeferredTimer == Timer)
115  {
116  CurrentTimer->NextDeferredTimer = Timer->NextDeferredTimer;
117  Timer->NextDeferredTimer = NULL;
118  return TRUE;
119  }
120  CurrentTimer = CurrentTimer->NextDeferredTimer;
121  }
122  return FALSE;
123  }
124 }
125 
126 /*
127  * @implemented
128  */
129 VOID
130 EXPORT
134 /*
135  * FUNCTION: cancel a scheduled NDIS_MINIPORT_TIMER
136  * ARGUMENTS:
137  * Timer: timer object to cancel
138  * TimerCancelled: status of cancel operation
139  * NOTES:
140  * - call at IRQL <= DISPATCH_LEVEL
141  */
142 {
143  //KIRQL OldIrql;
144 
147  ASSERT(Timer);
148 
150 
151 #if 0
152  if (*TimerCancelled)
153  {
154  KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql);
155  /* If it's somebody already dequeued it, something is wrong (maybe a double-cancel?) */
157  KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql);
158  }
159 #endif
160 }
161 
162 VOID NTAPI
167 {
169 
170 #if 0
171  /* Only dequeue if the timer has a period of 0 */
172  if (!Timer->Timer.Period)
173  {
174  KeAcquireSpinLockAtDpcLevel(&Timer->Miniport->Lock);
175  /* If someone already dequeued it, something is wrong (borked timer implementation?) */
177  KeReleaseSpinLockFromDpcLevel(&Timer->Miniport->Lock);
178  }
179 #endif
180 
181  Timer->MiniportTimerFunction(Dpc,
182  Timer->MiniportTimerContext,
185 }
186 
187 /*
188  * @implemented
189  */
190 VOID
191 EXPORT
197 /*
198  * FUNCTION: Initialize an NDIS_MINIPORT_TIMER
199  * ARGUMENTS:
200  * Timer: Timer object to initialize
201  * MiniportAdapterHandle: Handle to the miniport, passed in to MiniportInitialize
202  * TimerFunction: function to be executed when the timer expires
203  * FunctionContext: argument passed to TimerFunction when it is called
204  * NOTES:
205  * - TimerFunction is called at IRQL = DISPATCH_LEVEL
206  * - call at IRQL = PASSIVE_LEVEL
207  */
208 {
209  PAGED_CODE();
210  ASSERT(Timer);
211 
214 
215  Timer->MiniportTimerFunction = TimerFunction;
216  Timer->MiniportTimerContext = FunctionContext;
217  Timer->Miniport = &((PLOGICAL_ADAPTER)MiniportAdapterHandle)->NdisMiniportBlock;
218  Timer->NextDeferredTimer = NULL;
219 }
220 
221 /*
222  * @implemented
223  */
224 VOID
225 EXPORT
228  IN UINT MillisecondsPeriod)
229 /*
230  * FUNCTION: Set a timer to go off periodically
231  * ARGUMENTS:
232  * Timer: pointer to the timer object to set
233  * MillisecondsPeriod: period of the timer
234  * NOTES:
235  * - Minimum predictable interval is ~10ms
236  * - Must be called at IRQL <= DISPATCH_LEVEL
237  */
238 {
240  //KIRQL OldIrql;
241 
243  ASSERT(Timer);
244 
245  /* relative delays are negative, absolute are positive; resolution is 100ns */
246  Timeout.QuadPart = Int32x32To64(MillisecondsPeriod, -10000);
247 
248 #if 0
249  /* Lock the miniport block */
250  KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql);
251 
252  /* Attempt to dequeue the timer */
254 
255  /* Add the timer at the head of the timer queue */
256  Timer->NextDeferredTimer = Timer->Miniport->TimerQueue;
257  Timer->Miniport->TimerQueue = Timer;
258 
259  /* Unlock the miniport block */
260  KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql);
261 #endif
262 
263  KeSetTimerEx(&Timer->Timer, Timeout, MillisecondsPeriod, &Timer->Dpc);
264 }
265 
266 /*
267  * @implemented
268  */
269 #undef NdisMSetTimer
270 VOID
271 EXPORT
275 /*
276  * FUNCTION: Set a NDIS_MINIPORT_TIMER so that it goes off
277  * ARGUMENTS:
278  * Timer: timer object to set
279  * MillisecondsToDelay: time to wait for the timer to expire
280  * NOTES:
281  * - Minimum predictable interval is ~10ms
282  * - Must be called at IRQL <= DISPATCH_LEVEL
283  */
284 {
286  //KIRQL OldIrql;
287 
289  ASSERT(Timer);
290 
291  /* relative delays are negative, absolute are positive; resolution is 100ns */
292  Timeout.QuadPart = Int32x32To64(MillisecondsToDelay, -10000);
293 
294 #if 0
295  /* Lock the miniport block */
296  KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql);
297 
298  /* Attempt to dequeue the timer */
300 
301  /* Add the timer at the head of the timer queue */
302  Timer->NextDeferredTimer = Timer->Miniport->TimerQueue;
303  Timer->Miniport->TimerQueue = Timer;
304 
305  /* Unlock the miniport block */
306  KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql);
307 #endif
308 
309  KeSetTimer(&Timer->Timer, Timeout, &Timer->Dpc);
310 }
311 
312 /*
313  * @implemented
314  */
315 VOID
316 EXPORT
320 /*
321  * FUNCTION: Set an NDIS_TIMER so that it goes off
322  * ARGUMENTS:
323  * Timer: timer object to set
324  * MillisecondsToDelay: time to wait for the timer to expire
325  * NOTES:
326  * - Minimum predictable interval is ~10ms
327  * - Must be called at IRQL <= DISPATCH_LEVEL
328  */
329 {
331 
333  ASSERT(Timer);
334 
335  NDIS_DbgPrint(MAX_TRACE, ("Called. Timer is: 0x%x, Timeout is: %ld\n", Timer, MillisecondsToDelay));
336 
337  /* relative delays are negative, absolute are positive; resolution is 100ns */
338  Timeout.QuadPart = Int32x32To64(MillisecondsToDelay, -10000);
339 
340  KeSetTimer (&Timer->Timer, Timeout, &Timer->Dpc);
341 }
342 
343 /*
344  * @implemented
345  */
346 VOID
347 EXPORT
352 {
353  NDIS_DbgPrint(MAX_TRACE, ("Called. Timer is: 0x%x, Timeout is: %ld, FunctionContext is: 0x%x\n",
355 
356  Timer->Dpc.DeferredContext = FunctionContext;
357 
359 }
360 
361 /* EOF */
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
_In_ PNDIS_TIMER_FUNCTION TimerFunction
Definition: ndis.h:2811
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
_In_ NDIS_HANDLE MiniportAdapterHandle
Definition: ndis.h:4668
VOID NTAPI MiniTimerDpcFunction(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
Definition: time.c:163
_Out_ _At_ TimerCancelled PBOOLEAN TimerCancelled
Definition: ndis.h:2820
BOOLEAN DequeueMiniportTimer(PNDIS_MINIPORT_TIMER Timer)
Definition: time.c:94
VOID EXPORT NdisSetTimer(IN PNDIS_TIMER Timer, IN UINT MillisecondsToDelay)
Definition: time.c:317
BOOLEAN NTAPI KeSetTimerEx(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN LONG Period, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:294
#define PAGED_CODE()
Definition: video.h:57
_In_ PVOID FunctionContext
Definition: ndis.h:637
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
VOID EXPORT NdisMInitializeTimer(IN OUT PNDIS_MINIPORT_TIMER Timer, IN NDIS_HANDLE MiniportAdapterHandle, IN PNDIS_TIMER_FUNCTION TimerFunction, IN PVOID FunctionContext)
Definition: time.c:192
VOID EXPORT NdisMSetTimer(IN PNDIS_MINIPORT_TIMER Timer, IN UINT MillisecondsToDelay)
Definition: time.c:272
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:524
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _NDIS_MINIPORT_TIMER * NextDeferredTimer
Definition: ndis.h:2277
char * PBOOLEAN
Definition: retypes.h:11
VOID EXPORT NdisSetTimerEx(IN PNDIS_TIMER Timer, IN UINT MillisecondsToDelay, IN PVOID FunctionContext)
Definition: time.c:348
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
Definition: ketypes.h:687
struct _LOGICAL_ADAPTER * PLOGICAL_ADAPTER
KDEFERRED_ROUTINE * PKDEFERRED_ROUTINE
Definition: ketypes.h:678
NDIS_TIMER_FUNCTION * PNDIS_TIMER_FUNCTION
Definition: ndis.h:640
VOID EXPORT NdisGetCurrentSystemTime(IN OUT PLARGE_INTEGER pSystemTime)
Definition: time.c:51
VOID EXPORT NdisInitializeTimer(IN OUT PNDIS_TIMER Timer, IN PNDIS_TIMER_FUNCTION TimerFunction, IN PVOID FunctionContext)
Definition: time.c:71
_In_ UINT MillisecondsToDelay
Definition: ndis.h:2828
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
UINT Timer
Definition: capclock.c:11
static ULONG Timeout
Definition: ping.c:61
#define MAX_TRACE
Definition: debug.h:16
unsigned int UINT
Definition: ndis.h:50
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define NDIS_DbgPrint(_t_, _x_)
Definition: debug.h:40
#define OUT
Definition: typedefs.h:39
#define ASSERT_IRQL(x)
Definition: debug.h:42
VOID EXPORT NdisMSetPeriodicTimer(IN PNDIS_MINIPORT_TIMER Timer, IN UINT MillisecondsPeriod)
Definition: time.c:226
VOID EXPORT NdisMCancelTimer(IN PNDIS_MINIPORT_TIMER Timer, OUT PBOOLEAN TimerCancelled)
Definition: time.c:131
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711
VOID EXPORT NdisCancelTimer(IN PNDIS_TIMER Timer, OUT PBOOLEAN TimerCancelled)
Definition: time.c:27
#define Int32x32To64(a, b)
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675