Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeniotimer.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/io/iocomp.c 00005 * PURPOSE: I/O Wrappers for Executive Timers 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 */ 00008 00009 /* INCLUDES *****************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* GLOBALS *******************************************************************/ 00016 00017 /* Timer Database */ 00018 KSPIN_LOCK IopTimerLock; 00019 LIST_ENTRY IopTimerQueueHead; 00020 00021 /* Timer Firing */ 00022 KDPC IopTimerDpc; 00023 KTIMER IopTimer; 00024 00025 /* Keep count of how many timers we have */ 00026 ULONG IopTimerCount = 0; 00027 00028 /* PRIVATE FUNCTIONS *********************************************************/ 00029 00030 VOID 00031 NTAPI 00032 IopTimerDispatch(IN PKDPC Dpc, 00033 IN PVOID DeferredContext, 00034 IN PVOID SystemArgument1, 00035 IN PVOID SystemArgument2) 00036 { 00037 KIRQL OldIrql; 00038 PLIST_ENTRY TimerEntry; 00039 PIO_TIMER Timer; 00040 ULONG i; 00041 00042 /* Check if any Timers are actualyl enabled as of now */ 00043 if (IopTimerCount) 00044 { 00045 /* Lock the Timers */ 00046 KeAcquireSpinLock(&IopTimerLock, &OldIrql); 00047 00048 /* Call the Timer Routine of each enabled Timer */ 00049 for (TimerEntry = IopTimerQueueHead.Flink, i = IopTimerCount; 00050 (TimerEntry != &IopTimerQueueHead) && i; 00051 TimerEntry = TimerEntry->Flink) 00052 { 00053 /* Get the timer and check if it's enabled */ 00054 Timer = CONTAINING_RECORD(TimerEntry, IO_TIMER, IoTimerList); 00055 if (Timer->TimerEnabled) 00056 { 00057 /* Call the timer routine */ 00058 Timer->TimerRoutine(Timer->DeviceObject, Timer->Context); 00059 i--; 00060 } 00061 } 00062 00063 /* Unlock the Timers */ 00064 KeReleaseSpinLock(&IopTimerLock, OldIrql); 00065 } 00066 } 00067 00068 VOID 00069 NTAPI 00070 IopRemoveTimerFromTimerList(IN PIO_TIMER Timer) 00071 { 00072 KIRQL OldIrql; 00073 00074 /* Lock Timers */ 00075 KeAcquireSpinLock(&IopTimerLock, &OldIrql); 00076 00077 /* Remove Timer from the List and Drop the Timer Count if Enabled */ 00078 RemoveEntryList(&Timer->IoTimerList); 00079 if (Timer->TimerEnabled) IopTimerCount--; 00080 00081 /* Unlock the Timers */ 00082 KeReleaseSpinLock(&IopTimerLock, OldIrql); 00083 } 00084 00085 /* PUBLIC FUNCTIONS **********************************************************/ 00086 00087 /* 00088 * @implemented 00089 */ 00090 NTSTATUS 00091 NTAPI 00092 IoInitializeTimer(IN PDEVICE_OBJECT DeviceObject, 00093 IN PIO_TIMER_ROUTINE TimerRoutine, 00094 IN PVOID Context) 00095 { 00096 PIO_TIMER IoTimer = DeviceObject->Timer; 00097 PAGED_CODE(); 00098 00099 /* Check if we don't have a timer yet */ 00100 if (!IoTimer) 00101 { 00102 /* Allocate Timer */ 00103 IoTimer = ExAllocatePoolWithTag(NonPagedPool, 00104 sizeof(IO_TIMER), 00105 TAG_IO_TIMER); 00106 if (!IoTimer) return STATUS_INSUFFICIENT_RESOURCES; 00107 00108 /* Set up the Timer Structure */ 00109 RtlZeroMemory(IoTimer, sizeof(IO_TIMER)); 00110 IoTimer->Type = IO_TYPE_TIMER; 00111 IoTimer->DeviceObject = DeviceObject; 00112 DeviceObject->Timer = IoTimer; 00113 } 00114 00115 /* Setup the timer routine and context */ 00116 IoTimer->TimerRoutine = TimerRoutine; 00117 IoTimer->Context = Context; 00118 00119 /* Add it to the Timer List */ 00120 ExInterlockedInsertTailList(&IopTimerQueueHead, 00121 &IoTimer->IoTimerList, 00122 &IopTimerLock); 00123 00124 /* Return Success */ 00125 return STATUS_SUCCESS; 00126 } 00127 00128 /* 00129 * @implemented 00130 */ 00131 VOID 00132 NTAPI 00133 IoStartTimer(IN PDEVICE_OBJECT DeviceObject) 00134 { 00135 KIRQL OldIrql; 00136 PIO_TIMER IoTimer = DeviceObject->Timer; 00137 00138 /* Make sure the device isn't unloading */ 00139 if (!(((PEXTENDED_DEVOBJ_EXTENSION)(DeviceObject->DeviceObjectExtension))-> 00140 ExtensionFlags & (DOE_UNLOAD_PENDING | 00141 DOE_DELETE_PENDING | 00142 DOE_REMOVE_PENDING | 00143 DOE_REMOVE_PROCESSED))) 00144 { 00145 /* Lock Timers */ 00146 KeAcquireSpinLock(&IopTimerLock, &OldIrql); 00147 00148 /* Check if the timer isn't already enabled */ 00149 if (!IoTimer->TimerEnabled) 00150 { 00151 /* Enable it and increase the timer count */ 00152 IoTimer->TimerEnabled = TRUE; 00153 IopTimerCount++; 00154 } 00155 00156 /* Unlock Timers */ 00157 KeReleaseSpinLock(&IopTimerLock, OldIrql); 00158 } 00159 } 00160 00161 /* 00162 * @implemented 00163 */ 00164 VOID 00165 NTAPI 00166 IoStopTimer(PDEVICE_OBJECT DeviceObject) 00167 { 00168 KIRQL OldIrql; 00169 PIO_TIMER IoTimer = DeviceObject->Timer; 00170 00171 /* Lock Timers */ 00172 KeAcquireSpinLock(&IopTimerLock, &OldIrql); 00173 00174 /* Check if the timer is enabled */ 00175 if (IoTimer->TimerEnabled) 00176 { 00177 /* Disable it and decrease the timer count */ 00178 IoTimer->TimerEnabled = FALSE; 00179 IopTimerCount--; 00180 } 00181 00182 /* Unlock Timers */ 00183 KeReleaseSpinLock(&IopTimerLock, OldIrql); 00184 } 00185 00186 /* EOF */ Generated on Wed May 23 2012 04:35:09 for ReactOS by
1.7.6.1
|