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