Use upper-case ASSERT macros.
[reactos.git] / reactos / ntoskrnl / ke / kqueue.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PURPOSE: ReactOS kernel
4 * FILE: ntoskrnl/ke/kqueue.c
5 * PURPOSE: Implement device queues
6 * PROGRAMMER: David Welch (welch@mcmail.com)
7 * REVISION HISTORY:
8 * 08/07/98: Created
9 */
10
11 /* INCLUDES ****************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 /* FUNCTIONS *****************************************************************/
18
19
20 /*
21 * @implemented
22 */
23 BOOLEAN STDCALL
24 KeInsertByKeyDeviceQueue (
25 IN PKDEVICE_QUEUE DeviceQueue,
26 IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry,
27 IN ULONG SortKey)
28 {
29 DPRINT("KeInsertByKeyDeviceQueue()\n");
30 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
31
32 DeviceQueueEntry->SortKey=SortKey;
33
34 KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
35
36 if (!DeviceQueue->Busy)
37 {
38 DeviceQueue->Busy=TRUE;
39 KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
40 return(FALSE);
41 }
42
43 /* Insert new entry after the last entry with SortKey less or equal to passed-in SortKey */
44 InsertAscendingListFIFO(&DeviceQueue->DeviceListHead,
45 KDEVICE_QUEUE_ENTRY,
46 DeviceListEntry,
47 DeviceQueueEntry,
48 SortKey);
49
50 KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
51 return(TRUE);
52 }
53
54 /*
55 * @implemented
56 */
57 PKDEVICE_QUEUE_ENTRY
58 STDCALL
59 KeRemoveByKeyDeviceQueue (
60 IN PKDEVICE_QUEUE DeviceQueue,
61 IN ULONG SortKey
62 )
63 {
64 PLIST_ENTRY current;
65 PKDEVICE_QUEUE_ENTRY entry;
66
67 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
68 ASSERT(DeviceQueue!=NULL);
69 ASSERT(DeviceQueue->Busy);
70
71 KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
72
73 /* an attempt to remove an entry from an empty (and busy) queue sets the queue to idle */
74 if (IsListEmpty(&DeviceQueue->DeviceListHead))
75 {
76 DeviceQueue->Busy = FALSE;
77 KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
78 return NULL;
79 }
80
81 /* find entry with SortKey greater than or equal to the passed-in SortKey */
82 current = DeviceQueue->DeviceListHead.Flink;
83 while (current != &DeviceQueue->DeviceListHead)
84 {
85 entry = CONTAINING_RECORD(current,KDEVICE_QUEUE_ENTRY,DeviceListEntry);
86 if (entry->SortKey >= SortKey)
87 {
88 RemoveEntryList(current);
89 KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
90 return entry;
91 }
92 current = current->Flink;
93 }
94
95 /* if we didn't find a match, return the first entry */
96 current = RemoveHeadList(&DeviceQueue->DeviceListHead);
97 KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
98
99 return CONTAINING_RECORD(current,KDEVICE_QUEUE_ENTRY,DeviceListEntry);
100 }
101
102 /*
103 * @implemented
104 */
105 PKDEVICE_QUEUE_ENTRY
106 STDCALL
107 KeRemoveDeviceQueue (
108 IN PKDEVICE_QUEUE DeviceQueue)
109 /*
110 * FUNCTION: Removes an entry from a device queue
111 * ARGUMENTS:
112 * DeviceQueue = Queue to remove the entry
113 * RETURNS: The removed entry
114 */
115 {
116 PLIST_ENTRY list_entry;
117
118 DPRINT("KeRemoveDeviceQueue(DeviceQueue %x)\n",DeviceQueue);
119
120 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
121 ASSERT(DeviceQueue!=NULL);
122 ASSERT(DeviceQueue->Busy);
123
124 KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
125
126 /* an attempt to remove an entry from an empty (and busy) queue sets the queue idle */
127 if (IsListEmpty(&DeviceQueue->DeviceListHead))
128 {
129 DeviceQueue->Busy = FALSE;
130 KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
131 return NULL;
132 }
133
134 list_entry = RemoveHeadList(&DeviceQueue->DeviceListHead);
135 KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
136
137 return CONTAINING_RECORD(list_entry,KDEVICE_QUEUE_ENTRY,DeviceListEntry);
138 }
139
140 /*
141 * @implemented
142 */
143 VOID
144 STDCALL
145 KeInitializeDeviceQueue (
146 IN PKDEVICE_QUEUE DeviceQueue
147 )
148 /*
149 * FUNCTION: Intializes a device queue
150 * ARGUMENTS:
151 * DeviceQueue = Device queue to initialize
152 */
153 {
154 ASSERT(DeviceQueue!=NULL);
155 InitializeListHead(&DeviceQueue->DeviceListHead);
156 DeviceQueue->Busy=FALSE;
157 KeInitializeSpinLock(&DeviceQueue->Lock);
158 }
159
160 /*
161 * @implemented
162 */
163 BOOLEAN
164 STDCALL
165 KeInsertDeviceQueue (
166 IN PKDEVICE_QUEUE DeviceQueue,
167 IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry
168 )
169 /*
170 * FUNCTION: Inserts an entry in a device queue
171 * ARGUMENTS:
172 * DeviceQueue = Queue to insert the entry in
173 * DeviceQueueEntry = Entry to insert
174 * RETURNS: False is the device queue wasn't busy
175 * True otherwise
176 */
177 {
178 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
179
180 KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
181
182 if (!DeviceQueue->Busy)
183 {
184 DeviceQueue->Busy=TRUE;
185 KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
186 return(FALSE);
187 }
188
189 DeviceQueueEntry->SortKey=0;
190 InsertTailList(&DeviceQueue->DeviceListHead, &DeviceQueueEntry->DeviceListEntry);
191
192 KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
193 return(TRUE);
194 }
195
196
197 /*
198 * @implemented
199 */
200 BOOLEAN STDCALL
201 KeRemoveEntryDeviceQueue(
202 IN PKDEVICE_QUEUE DeviceQueue,
203 IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
204 {
205 PLIST_ENTRY current;
206 KIRQL oldIrql;
207 PKDEVICE_QUEUE_ENTRY entry;
208
209 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
210
211 KeAcquireSpinLock(&DeviceQueue->Lock, &oldIrql);
212
213 current = DeviceQueue->DeviceListHead.Flink;
214 while (current != &DeviceQueue->DeviceListHead)
215 {
216 entry = CONTAINING_RECORD(current, KDEVICE_QUEUE_ENTRY, DeviceListEntry);
217 if (DeviceQueueEntry == entry)
218 {
219 RemoveEntryList(current);
220 KeReleaseSpinLock(&DeviceQueue->Lock, oldIrql);
221 /* entry was in the queue (but not anymore) */
222 return TRUE;
223 }
224 current = current->Flink;
225 }
226
227 KeReleaseSpinLock(&DeviceQueue->Lock, oldIrql);
228
229 /* entry wasn't in the queue */
230 return FALSE;
231 }