Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendevqueue.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/ke/devqueue.c 00005 * PURPOSE: Implement device queues 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 /* FUNCTIONS *****************************************************************/ 00016 00017 /* 00018 * @implemented 00019 */ 00020 VOID 00021 NTAPI 00022 KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue) 00023 { 00024 /* Initialize the Header */ 00025 DeviceQueue->Type = DeviceQueueObject; 00026 DeviceQueue->Size = sizeof(KDEVICE_QUEUE); 00027 00028 /* Initialize the Listhead and Spinlock */ 00029 InitializeListHead(&DeviceQueue->DeviceListHead); 00030 KeInitializeSpinLock(&DeviceQueue->Lock); 00031 00032 /* Set it as busy */ 00033 DeviceQueue->Busy=FALSE; 00034 } 00035 00036 /* 00037 * @implemented 00038 */ 00039 BOOLEAN 00040 NTAPI 00041 KeInsertDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, 00042 IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry) 00043 { 00044 KLOCK_QUEUE_HANDLE DeviceLock; 00045 BOOLEAN Inserted; 00046 ASSERT_DEVICE_QUEUE(DeviceQueue); 00047 00048 DPRINT("KeInsertDeviceQueue() DevQueue %p, Entry %p\n", DeviceQueue, DeviceQueueEntry); 00049 00050 /* Lock the queue */ 00051 KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock); 00052 00053 /* Check if it's not busy */ 00054 if (!DeviceQueue->Busy) 00055 { 00056 /* Set it as busy */ 00057 Inserted = FALSE; 00058 DeviceQueue->Busy = TRUE; 00059 } 00060 else 00061 { 00062 /* Insert it into the list */ 00063 Inserted = TRUE; 00064 InsertTailList(&DeviceQueue->DeviceListHead, 00065 &DeviceQueueEntry->DeviceListEntry); 00066 } 00067 00068 /* Sert the Insert state into the entry */ 00069 DeviceQueueEntry->Inserted = Inserted; 00070 00071 /* Release the lock */ 00072 KiReleaseDeviceQueueLock(&DeviceLock); 00073 00074 /* Return the state */ 00075 return Inserted; 00076 } 00077 00078 /* 00079 * @implemented 00080 */ 00081 BOOLEAN 00082 NTAPI 00083 KeInsertByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, 00084 IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry, 00085 IN ULONG SortKey) 00086 { 00087 KLOCK_QUEUE_HANDLE DeviceLock; 00088 BOOLEAN Inserted; 00089 PLIST_ENTRY NextEntry; 00090 PKDEVICE_QUEUE_ENTRY LastEntry; 00091 ASSERT_DEVICE_QUEUE(DeviceQueue); 00092 00093 DPRINT("KeInsertByKeyDeviceQueue() DevQueue %p, Entry %p, SortKey 0x%x\n", DeviceQueue, DeviceQueueEntry, SortKey); 00094 00095 /* Lock the queue */ 00096 KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock); 00097 00098 /* Set the Sort Key */ 00099 DeviceQueueEntry->SortKey = SortKey; 00100 00101 /* Check if it's not busy */ 00102 if (!DeviceQueue->Busy) 00103 { 00104 /* Set it as busy */ 00105 Inserted = FALSE; 00106 DeviceQueue->Busy = TRUE; 00107 } 00108 else 00109 { 00110 /* Make sure the list isn't empty */ 00111 NextEntry = &DeviceQueue->DeviceListHead; 00112 if (!IsListEmpty(NextEntry)) 00113 { 00114 /* Get the last entry */ 00115 LastEntry = CONTAINING_RECORD(NextEntry->Blink, 00116 KDEVICE_QUEUE_ENTRY, 00117 DeviceListEntry); 00118 00119 /* Check if our sort key is lower */ 00120 if (SortKey < LastEntry->SortKey) 00121 { 00122 /* Loop each sort key */ 00123 do 00124 { 00125 /* Get the next entry */ 00126 NextEntry = NextEntry->Flink; 00127 LastEntry = CONTAINING_RECORD(NextEntry, 00128 KDEVICE_QUEUE_ENTRY, 00129 DeviceListEntry); 00130 00131 /* Keep looping until we find a place to insert */ 00132 } while (SortKey >= LastEntry->SortKey); 00133 } 00134 } 00135 00136 /* Now insert us */ 00137 InsertTailList(NextEntry, &DeviceQueueEntry->DeviceListEntry); 00138 Inserted = TRUE; 00139 } 00140 00141 /* Release the lock */ 00142 KiReleaseDeviceQueueLock(&DeviceLock); 00143 00144 /* Return the state */ 00145 return Inserted; 00146 } 00147 00148 /* 00149 * @implemented 00150 */ 00151 PKDEVICE_QUEUE_ENTRY 00152 NTAPI 00153 KeRemoveDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue) 00154 { 00155 PLIST_ENTRY ListEntry; 00156 PKDEVICE_QUEUE_ENTRY ReturnEntry; 00157 KLOCK_QUEUE_HANDLE DeviceLock; 00158 ASSERT_DEVICE_QUEUE(DeviceQueue); 00159 00160 DPRINT("KeRemoveDeviceQueue() DevQueue %p\n", DeviceQueue); 00161 00162 /* Lock the queue */ 00163 KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock); 00164 ASSERT(DeviceQueue->Busy); 00165 00166 /* Check if this is an empty queue */ 00167 if (IsListEmpty(&DeviceQueue->DeviceListHead)) 00168 { 00169 /* Set it to idle and return nothing*/ 00170 DeviceQueue->Busy = FALSE; 00171 ReturnEntry = NULL; 00172 } 00173 else 00174 { 00175 /* Remove the Entry from the List */ 00176 ListEntry = RemoveHeadList(&DeviceQueue->DeviceListHead); 00177 ReturnEntry = CONTAINING_RECORD(ListEntry, 00178 KDEVICE_QUEUE_ENTRY, 00179 DeviceListEntry); 00180 00181 /* Set it as non-inserted */ 00182 ReturnEntry->Inserted = FALSE; 00183 } 00184 00185 /* Release the lock */ 00186 KiReleaseDeviceQueueLock(&DeviceLock); 00187 00188 /* Return the entry */ 00189 return ReturnEntry; 00190 } 00191 00192 /* 00193 * @implemented 00194 */ 00195 PKDEVICE_QUEUE_ENTRY 00196 NTAPI 00197 KeRemoveByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, 00198 IN ULONG SortKey) 00199 { 00200 PLIST_ENTRY NextEntry; 00201 PKDEVICE_QUEUE_ENTRY ReturnEntry; 00202 KLOCK_QUEUE_HANDLE DeviceLock; 00203 ASSERT_DEVICE_QUEUE(DeviceQueue); 00204 00205 DPRINT("KeRemoveByKeyDeviceQueue() DevQueue %p, SortKey 0x%x\n", DeviceQueue, SortKey); 00206 00207 /* Lock the queue */ 00208 KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock); 00209 ASSERT(DeviceQueue->Busy); 00210 00211 /* Check if this is an empty queue */ 00212 if (IsListEmpty(&DeviceQueue->DeviceListHead)) 00213 { 00214 /* Set it to idle and return nothing*/ 00215 DeviceQueue->Busy = FALSE; 00216 ReturnEntry = NULL; 00217 } 00218 else 00219 { 00220 /* If SortKey is greater than the last key, then return the first entry right away */ 00221 NextEntry = &DeviceQueue->DeviceListHead; 00222 ReturnEntry = CONTAINING_RECORD(NextEntry->Blink, 00223 KDEVICE_QUEUE_ENTRY, 00224 DeviceListEntry); 00225 00226 /* Check if we can just get the first entry */ 00227 if (ReturnEntry->SortKey <= SortKey) 00228 { 00229 /* Get the first entry */ 00230 ReturnEntry = CONTAINING_RECORD(NextEntry->Flink, 00231 KDEVICE_QUEUE_ENTRY, 00232 DeviceListEntry); 00233 } 00234 else 00235 { 00236 /* Loop the list */ 00237 NextEntry = DeviceQueue->DeviceListHead.Flink; 00238 while (TRUE) 00239 { 00240 /* Make sure we don't go beyond the end of the queue */ 00241 ASSERT(NextEntry != &DeviceQueue->DeviceListHead); 00242 00243 /* Get the next entry and check if the key is low enough */ 00244 ReturnEntry = CONTAINING_RECORD(NextEntry, 00245 KDEVICE_QUEUE_ENTRY, 00246 DeviceListEntry); 00247 if (SortKey <= ReturnEntry->SortKey) break; 00248 00249 /* Try the next one */ 00250 NextEntry = NextEntry->Flink; 00251 } 00252 } 00253 00254 /* We have an entry, remove it now */ 00255 RemoveEntryList(&ReturnEntry->DeviceListEntry); 00256 00257 /* Set it as non-inserted */ 00258 ReturnEntry->Inserted = FALSE; 00259 } 00260 00261 /* Release the lock */ 00262 KiReleaseDeviceQueueLock(&DeviceLock); 00263 00264 /* Return the entry */ 00265 return ReturnEntry; 00266 } 00267 00268 /* 00269 * @implemented 00270 */ 00271 PKDEVICE_QUEUE_ENTRY 00272 NTAPI 00273 KeRemoveByKeyDeviceQueueIfBusy(IN PKDEVICE_QUEUE DeviceQueue, 00274 IN ULONG SortKey) 00275 { 00276 PLIST_ENTRY NextEntry; 00277 PKDEVICE_QUEUE_ENTRY ReturnEntry; 00278 KLOCK_QUEUE_HANDLE DeviceLock; 00279 ASSERT_DEVICE_QUEUE(DeviceQueue); 00280 00281 DPRINT("KeRemoveByKeyDeviceQueueIfBusy() DevQueue %p, SortKey 0x%x\n", DeviceQueue, SortKey); 00282 00283 /* Lock the queue */ 00284 KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock); 00285 00286 /* Check if this is an empty or idle queue */ 00287 if (!(DeviceQueue->Busy) || (IsListEmpty(&DeviceQueue->DeviceListHead))) 00288 { 00289 /* Set it to idle and return nothing*/ 00290 DeviceQueue->Busy = FALSE; 00291 ReturnEntry = NULL; 00292 } 00293 else 00294 { 00295 /* If SortKey is greater than the last key, then return the first entry right away */ 00296 NextEntry = &DeviceQueue->DeviceListHead; 00297 ReturnEntry = CONTAINING_RECORD(NextEntry->Blink, 00298 KDEVICE_QUEUE_ENTRY, 00299 DeviceListEntry); 00300 00301 /* Check if we can just get the first entry */ 00302 if (ReturnEntry->SortKey <= SortKey) 00303 { 00304 /* Get the first entry */ 00305 ReturnEntry = CONTAINING_RECORD(NextEntry->Flink, 00306 KDEVICE_QUEUE_ENTRY, 00307 DeviceListEntry); 00308 } 00309 else 00310 { 00311 /* Loop the list */ 00312 NextEntry = DeviceQueue->DeviceListHead.Flink; 00313 while (TRUE) 00314 { 00315 /* Make sure we don't go beyond the end of the queue */ 00316 ASSERT(NextEntry != &DeviceQueue->DeviceListHead); 00317 00318 /* Get the next entry and check if the key is low enough */ 00319 ReturnEntry = CONTAINING_RECORD(NextEntry, 00320 KDEVICE_QUEUE_ENTRY, 00321 DeviceListEntry); 00322 if (SortKey <= ReturnEntry->SortKey) break; 00323 00324 /* Try the next one */ 00325 NextEntry = NextEntry->Flink; 00326 } 00327 } 00328 00329 /* We have an entry, remove it now */ 00330 RemoveEntryList(&ReturnEntry->DeviceListEntry); 00331 00332 /* Set it as non-inserted */ 00333 ReturnEntry->Inserted = FALSE; 00334 } 00335 00336 /* Release the lock */ 00337 KiReleaseDeviceQueueLock(&DeviceLock); 00338 00339 /* Return the entry */ 00340 return ReturnEntry; 00341 } 00342 00343 /* 00344 * @implemented 00345 */ 00346 BOOLEAN 00347 NTAPI 00348 KeRemoveEntryDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, 00349 IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry) 00350 { 00351 BOOLEAN OldState; 00352 KLOCK_QUEUE_HANDLE DeviceLock; 00353 ASSERT_DEVICE_QUEUE(DeviceQueue); 00354 00355 DPRINT("KeRemoveEntryDeviceQueue() DevQueue %p, Entry %p\n", DeviceQueue, DeviceQueueEntry); 00356 00357 /* Lock the queue */ 00358 KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock); 00359 ASSERT(DeviceQueue->Busy); 00360 00361 /* Check the insertion state */ 00362 OldState = DeviceQueueEntry->Inserted; 00363 if (OldState) 00364 { 00365 /* Remove it */ 00366 DeviceQueueEntry->Inserted = FALSE; 00367 RemoveEntryList(&DeviceQueueEntry->DeviceListEntry); 00368 } 00369 00370 /* Unlock and return old state */ 00371 KiReleaseDeviceQueueLock(&DeviceLock); 00372 return OldState; 00373 } Generated on Sun May 27 2012 04:37:31 for ReactOS by
1.7.6.1
|