update for HEAD-2003091401
[reactos.git] / 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 <ddk/ntddk.h>
14
15 #define NDEBUG
16 #include <internal/debug.h>
17
18 /* FUNCTIONS *****************************************************************/
19
20 VOID 
21 InsertBeforeEntryInList(PLIST_ENTRY Head, PLIST_ENTRY After, PLIST_ENTRY Entry)
22 {
23    InsertHeadList(After, Entry);
24 }
25
26 /*
27  * @implemented
28  */
29 BOOLEAN STDCALL
30 KeInsertByKeyDeviceQueue (PKDEVICE_QUEUE                DeviceQueue,
31                           PKDEVICE_QUEUE_ENTRY  DeviceQueueEntry,
32                           ULONG                 SortKey)
33 {
34    KIRQL oldlvl;
35    PLIST_ENTRY current;
36    PKDEVICE_QUEUE_ENTRY entry;
37    
38    DPRINT("KeInsertByKeyDeviceQueue()\n");
39    
40    DeviceQueueEntry->SortKey=SortKey;
41
42    KeAcquireSpinLock(&DeviceQueue->Lock,&oldlvl);
43    
44    if (!DeviceQueue->Busy)
45      {
46         DeviceQueue->Busy=TRUE;
47         KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
48         return(FALSE);
49      }
50       
51    current=DeviceQueue->DeviceListHead.Flink;
52    while (current!=(&DeviceQueue->DeviceListHead))
53      {
54         entry = CONTAINING_RECORD(current,KDEVICE_QUEUE_ENTRY,DeviceListEntry);
55         if (entry->SortKey < SortKey)
56           {
57              InsertBeforeEntryInList(&DeviceQueue->DeviceListHead,
58                                      &DeviceQueueEntry->DeviceListEntry,
59                                      current);
60              KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
61              return(TRUE);
62           }
63         current = current->Flink;
64      }   
65    InsertTailList(&DeviceQueue->DeviceListHead,&DeviceQueueEntry->DeviceListEntry);
66    
67    KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
68    return(TRUE);
69 }
70
71 /*
72  * @implemented
73  */
74 PKDEVICE_QUEUE_ENTRY
75 STDCALL
76 KeRemoveByKeyDeviceQueue (
77         PKDEVICE_QUEUE  DeviceQueue,
78         ULONG           SortKey
79         )
80 {
81    KIRQL oldlvl;
82    PLIST_ENTRY current;
83    PKDEVICE_QUEUE_ENTRY entry;   
84    
85    assert_irql(DISPATCH_LEVEL);
86    assert(DeviceQueue!=NULL);
87    assert(DeviceQueue->Busy);
88    
89    KeAcquireSpinLock(&DeviceQueue->Lock,&oldlvl);
90    
91    current = DeviceQueue->DeviceListHead.Flink;
92    while (current != &DeviceQueue->DeviceListHead)
93      {
94         entry = CONTAINING_RECORD(current,KDEVICE_QUEUE_ENTRY,DeviceListEntry);
95         if (entry->SortKey < SortKey ||
96             current->Flink == &DeviceQueue->DeviceListHead)
97           {
98              RemoveEntryList(current);
99              KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
100              return(entry);
101           }
102         current = current->Flink;
103      }
104    DeviceQueue->Busy = FALSE;
105    KeReleaseSpinLock(&DeviceQueue->Lock, oldlvl);
106    return(NULL);
107 }
108
109 /*
110  * @implemented
111  */
112 PKDEVICE_QUEUE_ENTRY
113 STDCALL
114 KeRemoveDeviceQueue (
115         PKDEVICE_QUEUE  DeviceQueue
116         )
117 /*
118  * FUNCTION: Removes an entry from a device queue
119  * ARGUMENTS:
120  *        DeviceQueue = Queue to remove the entry
121  * RETURNS: The removed entry
122  */
123 {
124    KIRQL oldlvl;
125    PLIST_ENTRY list_entry;
126    PKDEVICE_QUEUE_ENTRY entry;
127    
128    DPRINT("KeRemoveDeviceQueue(DeviceQueue %x)\n",DeviceQueue);
129    
130    assert_irql(DISPATCH_LEVEL);
131    assert(DeviceQueue!=NULL);
132    assert(DeviceQueue->Busy);
133    
134    KeAcquireSpinLock(&DeviceQueue->Lock,&oldlvl);
135    
136    list_entry = RemoveHeadList(&DeviceQueue->DeviceListHead);
137    if (list_entry==(&DeviceQueue->DeviceListHead))
138      {
139         DeviceQueue->Busy=FALSE;
140         KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
141         return(NULL);
142      }
143    KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
144    
145    entry = CONTAINING_RECORD(list_entry,KDEVICE_QUEUE_ENTRY,DeviceListEntry);
146    return(entry);
147 }
148
149 /*
150  * @implemented
151  */
152 VOID
153 STDCALL
154 KeInitializeDeviceQueue (
155         PKDEVICE_QUEUE  DeviceQueue
156         )
157 /*
158  * FUNCTION: Intializes a device queue
159  * ARGUMENTS:
160  *       DeviceQueue = Device queue to initialize
161  */
162 {
163    assert(DeviceQueue!=NULL);
164    InitializeListHead(&DeviceQueue->DeviceListHead);
165    DeviceQueue->Busy=FALSE;
166    KeInitializeSpinLock(&DeviceQueue->Lock);
167 }
168
169 /*
170  * @implemented
171  */
172 BOOLEAN
173 STDCALL
174 KeInsertDeviceQueue (
175         PKDEVICE_QUEUE          DeviceQueue,
176         PKDEVICE_QUEUE_ENTRY    DeviceQueueEntry
177         )
178 /*
179  * FUNCTION: Inserts an entry in a device queue
180  * ARGUMENTS:
181  *        DeviceQueue = Queue to insert the entry in
182  *        DeviceQueueEntry = Entry to insert
183  * RETURNS: False is the device queue wasn't busy
184  *          True otherwise
185  */
186 {
187    KIRQL oldlvl;
188    
189    KeAcquireSpinLock(&DeviceQueue->Lock,&oldlvl);
190    
191    if (!DeviceQueue->Busy)
192      {
193         DeviceQueue->Busy=TRUE;
194         KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
195         return(FALSE);
196      }
197    
198    InsertTailList(&DeviceQueue->DeviceListHead,
199                   &DeviceQueueEntry->DeviceListEntry);
200    DeviceQueueEntry->SortKey=0;
201    
202    KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
203    return(TRUE);
204 }
205
206
207 /*
208  * @unimplemented
209  */
210 BOOLEAN STDCALL
211 KeRemoveEntryDeviceQueue(PKDEVICE_QUEUE DeviceQueue,
212                          PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
213 {
214   UNIMPLEMENTED;
215   return(FALSE);
216 }