ReactOS 0.4.15-dev-7788-g1ad9096
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

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file timerobj.c.

Function Documentation

◆ KeCancelTimer()

BOOLEAN NTAPI KeCancelTimer ( IN OUT PKTIMER  Timer)

Definition at line 206 of file timerobj.c.

207{
209 BOOLEAN Inserted;
212 DPRINT("KeCancelTimer(): Timer %p\n", Timer);
213
214 /* Lock the Database and Raise IRQL */
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 */
223
224 /* Return the old state */
225 return Inserted;
226}
unsigned char BOOLEAN
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
FORCEINLINE VOID KiReleaseDispatcherLock(IN KIRQL OldIrql)
Definition: ke_x.h:157
FORCEINLINE VOID KxRemoveTreeTimer(IN PKTIMER Timer)
Definition: ke_x.h:1004
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:149
#define ASSERT(a)
Definition: mode.c:44
#define DPRINT
Definition: sndvol32.h:71
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define ASSERT_TIMER(Object)

Referenced by _Function_class_(), _Requires_lock_held_(), BeepClose(), BeepStartIo(), BeepUnload(), ClasspDisableTimer(), ClasspStopIdleTimer(), CmpShutdownWorkers(), DispCancelRequest(), ExpDeleteTimer(), ExpWorkerThreadBalanceManager(), ExTimerRundown(), FatDeleteVcb(), FreeDeviceData(), HandleRemoveDevice(), HandleStopDevice(), HandleSurpriseRemoval(), i8042MouDpcRoutine(), KsStreamPointerCancelTimeout(), MsfsWrite(), NdisCancelTimer(), NdisIPnPStopDevice(), NdisMCancelTimer(), NpCancelWaiter(), NpCancelWaitQueueIrp(), NtCancelTimer(), NtSetTimer(), ReadBytes(), ReceiveDatagram(), ScratchBuffer_ReadWriteEvtRequestCancel(), ScsiPortDpcForIsr(), SignalSocket(), StartMotor(), MxTimer::Stop(), SubmitIdleRequestIrp(), TCPSendEventHandler(), TiUnload(), USBH_SyncIrpComplete(), and CMiniportDMusUARTStream::~CMiniportDMusUARTStream().

◆ KeInitializeTimer()

◆ KeInitializeTimerEx()

VOID NTAPI KeInitializeTimerEx ( OUT PKTIMER  Timer,
IN TIMER_TYPE  Type 
)

Definition at line 244 of file timerobj.c.

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:7
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
@ TimerNotificationObject
Definition: ketypes.h:414
uint32_t ULONG
Definition: typedefs.h:59
struct _KTIMER KTIMER

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

◆ KeReadStateTimer()

BOOLEAN NTAPI KeReadStateTimer ( IN PKTIMER  Timer)

Definition at line 269 of file timerobj.c.

270{
271 /* Return the Signal State */
273 return (BOOLEAN)Timer->Header.SignalState;
274}

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

◆ KeSetTimer()

BOOLEAN NTAPI KeSetTimer ( IN OUT PKTIMER  Timer,
IN LARGE_INTEGER  DueTime,
IN PKDPC Dpc  OPTIONAL 
)

◆ KeSetTimerEx()

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.

298{
300 BOOLEAN Inserted;
301 ULONG Hand = 0;
302 BOOLEAN RequestInterrupt = FALSE;
305 DPRINT("KeSetTimerEx(): Timer %p, DueTime %I64d, Period %d, Dpc %p\n",
306 Timer, DueTime.QuadPart, Period, Dpc);
307
308 /* Lock the Database and Raise IRQL */
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 */
338
339 /* Return old state */
340 return Inserted;
341}
#define FALSE
Definition: types.h:117
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:271
FORCEINLINE BOOLEAN KiComputeDueTime(IN PKTIMER Timer, IN LARGE_INTEGER DueTime, OUT PULONG Hand)
Definition: ke_x.h:952
FORCEINLINE VOID KiReleaseDispatcherLockFromSynchLevel(VOID)
Definition: ke_x.h:174
FORCEINLINE VOID KxInsertTimer(IN PKTIMER Timer, IN ULONG Hand)
Definition: ke_x.h:923
VOID FASTCALL KiExitDispatcher(KIRQL OldIrql)
BOOLEAN FASTCALL KiSignalTimer(IN PKTIMER Timer)
Definition: timerobj.c:114
_In_ LARGE_INTEGER _In_ ULONG Period
Definition: kefuncs.h:1313

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

◆ KiCompleteTimer()

VOID FASTCALL KiCompleteTimer ( IN PKTIMER  Timer,
IN PKSPIN_LOCK_QUEUE  LockQueue 
)

Definition at line 167 of file timerobj.c.

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}
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
FORCEINLINE VOID KiRemoveEntryTimer(IN PKTIMER Timer)
Definition: ke_x.h:892
FORCEINLINE VOID KiReleaseTimerLock(IN PKSPIN_LOCK_QUEUE LockQueue)
Definition: ke_x.h:297
FORCEINLINE VOID KiAcquireDispatcherLockAtSynchLevel(VOID)
Definition: ke_x.h:165
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121

Referenced by KxInsertTimer().

◆ KiInsertTimerTable()

BOOLEAN FASTCALL KiInsertTimerTable ( IN PKTIMER  Timer,
IN ULONG  Hand 
)

Definition at line 63 of file timerobj.c.

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 */
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
#define InsertHeadList(ListHead, Entry)
FORCEINLINE ULONG KiComputeTimerTableIndex(IN ULONGLONG DueTime)
Definition: ke_x.h:881
#define KeQueryInterruptTime()
Definition: ke.h:37
ULARGE_INTEGER Time
Definition: ketypes.h:779
LIST_ENTRY Entry
Definition: ketypes.h:778
ULARGE_INTEGER DueTime
Definition: ketypes.h:853
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
KTIMER_TABLE_ENTRY KiTimerTableListHead[TIMER_TABLE_SIZE]
Definition: timerobj.c:17
int64_t LONGLONG
Definition: typedefs.h:68
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint64_t ULONGLONG
Definition: typedefs.h:67
LONGLONG QuadPart
Definition: typedefs.h:114

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

◆ KiInsertTreeTimer()

BOOLEAN FASTCALL KiInsertTreeTimer ( IN PKTIMER  Timer,
IN LARGE_INTEGER  Interval 
)

Definition at line 26 of file timerobj.c.

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}
FORCEINLINE PKSPIN_LOCK_QUEUE KiAcquireTimerLock(IN ULONG Hand)
Definition: ke_x.h:286
DWORD Interval
Definition: netstat.c:30
BOOLEAN FASTCALL KiInsertTimerTable(IN PKTIMER Timer, IN ULONG Hand)
Definition: timerobj.c:63

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

◆ KiSignalTimer()

BOOLEAN FASTCALL KiSignalTimer ( IN PKTIMER  Timer)

Definition at line 114 of file timerobj.c.

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);
148 }
149
150 /* Check if we have a DPC */
151 if (Dpc)
152 {
153 /* Insert it in the queue */
154 KeQuerySystemTime(&SystemTime);
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 ULongToPtr(ul)
Definition: basetsd.h:92
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:725
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
FORCEINLINE VOID KxUnwaitThread(IN DISPATCHER_HEADER *Object, IN KPRIORITY Increment)
Definition: ke_x.h:1259
FORCEINLINE VOID KxUnwaitThreadForEvent(IN PKEVENT Event, IN KPRIORITY Increment)
Definition: ke_x.h:1304
#define Int32x32To64(a, b)
Definition: ketypes.h:699
BOOLEAN FASTCALL KiInsertTreeTimer(IN PKTIMER Timer, IN LARGE_INTEGER Interval)
Definition: timerobj.c:26
ULONG LowPart
Definition: typedefs.h:106
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by KeSetTimerEx(), and KiCompleteTimer().

Variable Documentation

◆ KiEnableTimerWatchdog

BOOLEAN KiEnableTimerWatchdog = FALSE

Definition at line 20 of file timerobj.c.

Referenced by NmiDbgCallback().

◆ KiTimeIncrementReciprocal

LARGE_INTEGER KiTimeIncrementReciprocal

Definition at line 18 of file timerobj.c.

Referenced by KiInitializeKernel().

◆ KiTimeIncrementShiftCount

UCHAR KiTimeIncrementShiftCount

Definition at line 19 of file timerobj.c.

Referenced by KiInitializeKernel().

◆ KiTimerTableListHead