ReactOS  r75214
timerobj.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for timerobj.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

BOOLEAN FASTCALL KiInsertTreeTimer (IN PKTIMER Timer, IN LARGE_INTEGER Interval)
 
BOOLEAN FASTCALL KiInsertTimerTable (IN PKTIMER Timer, IN ULONG Hand)
 
BOOLEAN FASTCALL KiSignalTimer (IN PKTIMER Timer)
 
VOID FASTCALL KiCompleteTimer (IN PKTIMER Timer, IN PKSPIN_LOCK_QUEUE LockQueue)
 
BOOLEAN NTAPI KeCancelTimer (IN OUT PKTIMER Timer)
 
VOID NTAPI KeInitializeTimer (OUT PKTIMER Timer)
 
VOID NTAPI KeInitializeTimerEx (OUT PKTIMER Timer, IN TIMER_TYPE Type)
 
BOOLEAN NTAPI KeReadStateTimer (IN PKTIMER Timer)
 
BOOLEAN NTAPI KeSetTimer (IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
 
BOOLEAN NTAPI KeSetTimerEx (IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN LONG Period, IN PKDPC Dpc OPTIONAL)
 

Variables

KTIMER_TABLE_ENTRY KiTimerTableListHead [TIMER_TABLE_SIZE]
 
LARGE_INTEGER KiTimeIncrementReciprocal
 
UCHAR KiTimeIncrementShiftCount
 
BOOLEAN KiEnableTimerWatchdog = FALSE
 

Macro Definition Documentation

#define NDEBUG

Definition at line 12 of file timerobj.c.

Function Documentation

BOOLEAN NTAPI KeCancelTimer ( IN OUT PKTIMER  Timer)

Definition at line 206 of file timerobj.c.

Referenced by BeepClose(), BeepStartIo(), BeepUnload(), CmpShutdownWorkers(), DispCancelRequest(), ExpDeleteTimer(), ExpWorkerThreadBalanceManager(), ExTimerRundown(), flush_thread(), FreeDeviceData(), HandleRemoveDevice(), HandleStopDevice(), HandleSurpriseRemoval(), i8042MouDpcRoutine(), KsStreamPointerCancelTimeout(), MsfsWrite(), NdisCancelTimer(), NdisIPnPStopDevice(), NdisMCancelTimer(), NpCancelWaiter(), NpCancelWaitQueueIrp(), NtCancelTimer(), NtSetTimer(), ReadBytes(), RemovePiceRunningTimer(), ScsiPortDpcForIsr(), SignalSocket(), StartMotor(), SubmitIdleRequestIrp(), TCPDisconnect(), TCPSendEventHandler(), TiUnload(), and CMiniportDMusUARTStream::~CMiniportDMusUARTStream().

207 {
208  KIRQL OldIrql;
209  BOOLEAN Inserted;
212  DPRINT("KeCancelTimer(): Timer %p\n", Timer);
213 
214  /* Lock the Database and Raise IRQL */
215  OldIrql = KiAcquireDispatcherLock();
216 
217  /* Check if it's inserted, and remove it if it is */
218  Inserted = Timer->Header.Inserted;
219  if (Inserted) KxRemoveTreeTimer(Timer);
220 
221  /* Release Dispatcher Lock */
222  KiReleaseDispatcherLock(OldIrql);
223 
224  /* Return the old state */
225  return Inserted;
226 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
FORCEINLINE VOID KxRemoveTreeTimer(IN PKTIMER Timer)
Definition: ke_x.h:995
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define ASSERT_TIMER(Object)
void DPRINT(...)
Definition: polytest.cpp:61
unsigned char BOOLEAN
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
FORCEINLINE VOID KiReleaseDispatcherLock(IN KIRQL OldIrql)
Definition: ke_x.h:152
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:144
VOID NTAPI KeInitializeTimerEx ( OUT PKTIMER  Timer,
IN TIMER_TYPE  Type 
)

Definition at line 244 of file timerobj.c.

Referenced by AfdSelect(), FreeBT_AddDevice(), IoInitSystem(), KeBalanceSetManager(), KeInitializeTimer(), MiInitBalancerThread(), NtCreateTimer(), PoInitializePrcb(), and TestTimerFunctional().

246 {
247  DPRINT("KeInitializeTimerEx(): Timer %p, Type %s\n",
249  "NotificationTimer" : "SynchronizationTimer");
250 
251  /* Initialize the Dispatch Header */
252  Timer->Header.Type = TimerNotificationObject + Type;
253  //Timer->Header.TimerControlFlags = 0; // win does not init this field
254  Timer->Header.Hand = sizeof(KTIMER) / sizeof(ULONG);
255  Timer->Header.Inserted = 0; // win7: Timer->Header.TimerMiscFlags = 0;
256  Timer->Header.SignalState = 0;
257  InitializeListHead(&(Timer->Header.WaitListHead));
258 
259  /* Initialize the Other data */
260  Timer->DueTime.QuadPart = 0;
261  Timer->Period = 0;
262 }
Type
Definition: Type.h:6
struct _KTIMER KTIMER
void DPRINT(...)
Definition: polytest.cpp:61
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN NTAPI KeReadStateTimer ( IN PKTIMER  Timer)

Definition at line 269 of file timerobj.c.

Referenced by NtCancelTimer(), NtQueryTimer(), and NtSetTimer().

270 {
271  /* Return the Signal State */
273  return (BOOLEAN)Timer->Header.SignalState;
274 }
#define ASSERT_TIMER(Object)
unsigned char BOOLEAN
BOOLEAN NTAPI KeSetTimerEx ( IN OUT PKTIMER  Timer,
IN LARGE_INTEGER  DueTime,
IN LONG  Period,
IN PKDPC Dpc  OPTIONAL 
)

Definition at line 294 of file timerobj.c.

Referenced by ClasspRetryDpcTimer(), DriverEntry(), HandleStartDevice(), IdleNotificationRequestComplete(), InitializeDeviceData(), InitPiceRunningTimer(), IoInitSystem(), KeBalanceSetManager(), KeSetTimer(), MiInitBalancerThread(), NdisIPnPStartDevice(), NdisMSetPeriodicTimer(), and NtSetTimer().

298 {
299  KIRQL OldIrql;
300  BOOLEAN Inserted;
301  ULONG Hand = 0;
302  BOOLEAN RequestInterrupt = FALSE;
305  DPRINT("KeSetTimerEx(): Timer %p, DueTime %I64d, Period %d, Dpc %p\n",
307 
308  /* Lock the Database and Raise IRQL */
309  OldIrql = KiAcquireDispatcherLock();
310 
311  /* Check if it's inserted, and remove it if it is */
312  Inserted = Timer->Header.Inserted;
313  if (Inserted) KxRemoveTreeTimer(Timer);
314 
315  /* Set Default Timer Data */
316  Timer->Dpc = Dpc;
317  Timer->Period = Period;
318  if (!KiComputeDueTime(Timer, DueTime, &Hand))
319  {
320  /* Signal the timer */
321  RequestInterrupt = KiSignalTimer(Timer);
322 
323  /* Release the dispatcher lock */
325 
326  /* Check if we need to do an interrupt */
327  if (RequestInterrupt) HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
328  }
329  else
330  {
331  /* Insert the timer */
332  Timer->Header.SignalState = FALSE;
333  KxInsertTimer(Timer, Hand);
334  }
335 
336  /* Exit the dispatcher */
337  KiExitDispatcher(OldIrql);
338 
339  /* Return old state */
340  return Inserted;
341 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
_In_ LARGE_INTEGER DueTime
Definition: kefuncs.h:524
FORCEINLINE BOOLEAN KiComputeDueTime(IN PKTIMER Timer, IN LARGE_INTEGER DueTime, OUT PULONG Hand)
Definition: ke_x.h:943
FORCEINLINE VOID KxRemoveTreeTimer(IN PKTIMER Timer)
Definition: ke_x.h:995
_In_ LARGE_INTEGER _In_ ULONG Period
Definition: kefuncs.h:1268
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define ASSERT_TIMER(Object)
void DPRINT(...)
Definition: polytest.cpp:61
FORCEINLINE VOID KxInsertTimer(IN PKTIMER Timer, IN ULONG Hand)
Definition: ke_x.h:915
VOID FASTCALL KiExitDispatcher(KIRQL OldIrql)
unsigned char BOOLEAN
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:524
BOOLEAN FASTCALL KiSignalTimer(IN PKTIMER Timer)
Definition: timerobj.c:114
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:271
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:144
FORCEINLINE VOID KiReleaseDispatcherLockFromDpcLevel(VOID)
Definition: ke_x.h:168
unsigned int ULONG
Definition: retypes.h:1
LONGLONG QuadPart
Definition: typedefs.h:113
VOID FASTCALL KiCompleteTimer ( IN PKTIMER  Timer,
IN PKSPIN_LOCK_QUEUE  LockQueue 
)

Definition at line 167 of file timerobj.c.

Referenced by KxInsertTimer().

169 {
170  LIST_ENTRY ListHead;
171  BOOLEAN RequestInterrupt = FALSE;
172  DPRINT("KiCompleteTimer(): Timer %p, LockQueue: %p\n", Timer, LockQueue);
173 
174  /* Remove it from the timer list */
176 
177  /* Link the timer list to our stack */
178  ListHead.Flink = &Timer->TimerListEntry;
179  ListHead.Blink = &Timer->TimerListEntry;
180  Timer->TimerListEntry.Flink = &ListHead;
181  Timer->TimerListEntry.Blink = &ListHead;
182 
183  /* Release the timer lock */
184  KiReleaseTimerLock(LockQueue);
185 
186  /* Acquire dispatcher lock */
188 
189  /* Signal the timer if it's still on our list */
190  if (!IsListEmpty(&ListHead)) RequestInterrupt = KiSignalTimer(Timer);
191 
192  /* Release the dispatcher lock */
194 
195  /* Request a DPC if needed */
196  if (RequestInterrupt) HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
197 }
struct _LIST_ENTRY * Blink
Definition: typedefs.h:121
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define FALSE
Definition: types.h:117
void DPRINT(...)
Definition: polytest.cpp:61
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
unsigned char BOOLEAN
BOOLEAN FASTCALL KiSignalTimer(IN PKTIMER Timer)
Definition: timerobj.c:114
Definition: typedefs.h:118
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:271
FORCEINLINE VOID KiRemoveEntryTimer(IN PKTIMER Timer)
Definition: ke_x.h:884
FORCEINLINE VOID KiReleaseDispatcherLockFromDpcLevel(VOID)
Definition: ke_x.h:168
FORCEINLINE VOID KiReleaseTimerLock(IN PKSPIN_LOCK_QUEUE LockQueue)
Definition: ke_x.h:291
FORCEINLINE VOID KiAcquireDispatcherLockAtDpcLevel(VOID)
Definition: ke_x.h:160
BOOLEAN FASTCALL KiInsertTimerTable ( IN PKTIMER  Timer,
IN ULONG  Hand 
)

Definition at line 63 of file timerobj.c.

Referenced by KeSetSystemTime(), KiInsertTreeTimer(), and KxInsertTimer().

65 {
66  LARGE_INTEGER InterruptTime;
67  LONGLONG DueTime = Timer->DueTime.QuadPart;
68  BOOLEAN Expired = FALSE;
69  PLIST_ENTRY ListHead, NextEntry;
70  PKTIMER CurrentTimer;
71  DPRINT("KiInsertTimerTable(): Timer %p, Hand: %lu\n", Timer, Hand);
72 
73  /* Check if the period is zero */
74  if (!Timer->Period) Timer->Header.SignalState = FALSE;
75 
76  /* Sanity check */
77  ASSERT(Hand == KiComputeTimerTableIndex(DueTime));
78 
79  /* Loop the timer list backwards */
80  ListHead = &KiTimerTableListHead[Hand].Entry;
81  NextEntry = ListHead->Blink;
82  while (NextEntry != ListHead)
83  {
84  /* Get the timer */
85  CurrentTimer = CONTAINING_RECORD(NextEntry, KTIMER, TimerListEntry);
86 
87  /* Now check if we can fit it before */
88  if ((ULONGLONG)DueTime >= CurrentTimer->DueTime.QuadPart) break;
89 
90  /* Keep looping */
91  NextEntry = NextEntry->Blink;
92  }
93 
94  /* Looped all the list, insert it here and get the interrupt time again */
95  InsertHeadList(NextEntry, &Timer->TimerListEntry);
96 
97  /* Check if we didn't find it in the list */
98  if (NextEntry == ListHead)
99  {
100  /* Set the time */
102 
103  /* Make sure it hasn't expired already */
104  InterruptTime.QuadPart = KeQueryInterruptTime();
105  if (DueTime <= InterruptTime.QuadPart) Expired = TRUE;
106  }
107 
108  /* Return expired state */
109  return Expired;
110 }
#define TRUE
Definition: types.h:120
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
_In_ LARGE_INTEGER DueTime
Definition: kefuncs.h:524
struct _LIST_ENTRY * Blink
Definition: typedefs.h:121
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define FALSE
Definition: types.h:117
void DPRINT(...)
Definition: polytest.cpp:61
ULARGE_INTEGER Time
Definition: ketypes.h:667
int64_t LONGLONG
Definition: typedefs.h:67
unsigned char BOOLEAN
LIST_ENTRY Entry
Definition: ketypes.h:666
uint64_t ULONGLONG
Definition: typedefs.h:66
ULARGE_INTEGER DueTime
Definition: ketypes.h:826
Definition: typedefs.h:118
KTIMER_TABLE_ENTRY KiTimerTableListHead[TIMER_TABLE_SIZE]
Definition: timerobj.c:17
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
ULONGLONG NTAPI KeQueryInterruptTime(VOID)
Definition: clock.c:203
FORCEINLINE ULONG KiComputeTimerTableIndex(IN ULONGLONG DueTime)
Definition: ke_x.h:873
LONGLONG QuadPart
Definition: typedefs.h:113
BOOLEAN FASTCALL KiInsertTreeTimer ( IN PKTIMER  Timer,
IN LARGE_INTEGER  Interval 
)

Definition at line 26 of file timerobj.c.

Referenced by KiSignalTimer(), KiTimerExpiration(), and KiTimerListExpire().

28 {
29  BOOLEAN Inserted = FALSE;
30  ULONG Hand = 0;
31  PKSPIN_LOCK_QUEUE LockQueue;
32  DPRINT("KiInsertTreeTimer(): Timer %p, Interval: %I64d\n", Timer, Interval.QuadPart);
33 
34  /* Setup the timer's due time */
35  if (KiComputeDueTime(Timer, Interval, &Hand))
36  {
37  /* Acquire the lock */
38  LockQueue = KiAcquireTimerLock(Hand);
39 
40  /* Insert the timer */
41  if (KiInsertTimerTable(Timer, Hand))
42  {
43  /* It was already there, remove it */
45  Timer->Header.Inserted = FALSE;
46  }
47  else
48  {
49  /* Otherwise, we're now inserted */
50  Inserted = TRUE;
51  }
52 
53  /* Release the lock */
54  KiReleaseTimerLock(LockQueue);
55  }
56 
57  /* Release the lock and return insert status */
58  return Inserted;
59 }
#define TRUE
Definition: types.h:120
FORCEINLINE BOOLEAN KiComputeDueTime(IN PKTIMER Timer, IN LARGE_INTEGER DueTime, OUT PULONG Hand)
Definition: ke_x.h:943
FORCEINLINE PKSPIN_LOCK_QUEUE KiAcquireTimerLock(IN ULONG Hand)
Definition: ke_x.h:280
#define FALSE
Definition: types.h:117
void DPRINT(...)
Definition: polytest.cpp:61
DWORD Interval
Definition: netstat.c:30
unsigned char BOOLEAN
BOOLEAN FASTCALL KiInsertTimerTable(IN PKTIMER Timer, IN ULONG Hand)
Definition: timerobj.c:63
FORCEINLINE VOID KiRemoveEntryTimer(IN PKTIMER Timer)
Definition: ke_x.h:884
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID KiReleaseTimerLock(IN PKSPIN_LOCK_QUEUE LockQueue)
Definition: ke_x.h:291
BOOLEAN FASTCALL KiSignalTimer ( IN PKTIMER  Timer)

Definition at line 114 of file timerobj.c.

Referenced by KeSetTimerEx(), and KiCompleteTimer().

115 {
116  BOOLEAN RequestInterrupt = FALSE;
117  PKDPC Dpc = Timer->Dpc;
118  ULONG Period = Timer->Period;
119  LARGE_INTEGER Interval, SystemTime;
120  DPRINT("KiSignalTimer(): Timer %p\n", Timer);
121 
122  /* Set default values */
123  Timer->Header.Inserted = FALSE;
124  Timer->Header.SignalState = TRUE;
125 
126  /* Check if the timer has waiters */
127  if (!IsListEmpty(&Timer->Header.WaitListHead))
128  {
129  /* Check the type of event */
130  if (Timer->Header.Type == TimerNotificationObject)
131  {
132  /* Unwait the thread */
134  }
135  else
136  {
137  /* Otherwise unwait the thread and signal the timer */
139  }
140  }
141 
142  /* Check if we have a period */
143  if (Period)
144  {
145  /* Calculate the interval and insert the timer */
146  Interval.QuadPart = Int32x32To64(Period, -10000);
147  while (!KiInsertTreeTimer(Timer, Interval));
148  }
149 
150  /* Check if we have a DPC */
151  if (Dpc)
152  {
153  /* Insert it in the queue */
154  KeQuerySystemTime(&SystemTime);
155  KeInsertQueueDpc(Dpc,
156  ULongToPtr(SystemTime.LowPart),
157  ULongToPtr(SystemTime.HighPart));
158  RequestInterrupt = TRUE;
159  }
160 
161  /* Return whether we need to request a DPC interrupt or not */
162  return RequestInterrupt;
163 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define TRUE
Definition: types.h:120
#define ULongToPtr(ul)
Definition: basetsd.h:91
FORCEINLINE VOID KxUnwaitThreadForEvent(IN PKEVENT Event, IN KPRIORITY Increment)
Definition: ke_x.h:1295
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:724
_In_ LARGE_INTEGER _In_ ULONG Period
Definition: kefuncs.h:1268
BOOLEAN FASTCALL KiInsertTreeTimer(IN PKTIMER Timer, IN LARGE_INTEGER Interval)
Definition: timerobj.c:26
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define FALSE
Definition: types.h:117
void DPRINT(...)
Definition: polytest.cpp:61
DWORD Interval
Definition: netstat.c:30
unsigned char BOOLEAN
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:524
Definition: ketypes.h:672
ULONG LowPart
Definition: typedefs.h:105
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
FORCEINLINE VOID KxUnwaitThread(IN DISPATCHER_HEADER *Object, IN KPRIORITY Increment)
Definition: ke_x.h:1250
#define Int32x32To64(a, b)
LONGLONG QuadPart
Definition: typedefs.h:113

Variable Documentation

BOOLEAN KiEnableTimerWatchdog = FALSE

Definition at line 20 of file timerobj.c.

Referenced by NmiDbgCallback().

LARGE_INTEGER KiTimeIncrementReciprocal

Definition at line 18 of file timerobj.c.

Referenced by KiInitializeKernel().

UCHAR KiTimeIncrementShiftCount

Definition at line 19 of file timerobj.c.

Referenced by KiInitializeKernel().