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)
11 /* INCLUDES ****************************************************************/
13 #include <ddk/ntddk.h>
16 #include <internal/debug.h>
18 /* FUNCTIONS *****************************************************************/
20 VOID
InsertBeforeEntryInList(PLIST_ENTRY Head
, PLIST_ENTRY After
,
23 InsertHeadList(After
, Entry
);
26 BOOLEAN
KeInsertByKeyDeviceQueue(PKDEVICE_QUEUE DeviceQueue
,
27 PKDEVICE_QUEUE_ENTRY DeviceQueueEntry
,
32 PKDEVICE_QUEUE_ENTRY entry
;
34 DPRINT("KeInsertByKeyDeviceQueue()\n");
36 DeviceQueueEntry
->Key
=SortKey
;
38 KeAcquireSpinLock(&DeviceQueue
->Lock
,&oldlvl
);
40 if (!DeviceQueue
->Busy
)
42 DeviceQueue
->Busy
=TRUE
;
43 KeReleaseSpinLock(&DeviceQueue
->Lock
,oldlvl
);
47 current
=DeviceQueue
->ListHead
.Flink
;
48 while (current
!=(&DeviceQueue
->ListHead
))
50 entry
= CONTAINING_RECORD(current
,KDEVICE_QUEUE_ENTRY
,Entry
);
51 if (entry
->Key
< SortKey
)
53 InsertBeforeEntryInList(&DeviceQueue
->ListHead
,
54 &DeviceQueueEntry
->Entry
,
56 KeReleaseSpinLock(&DeviceQueue
->Lock
,oldlvl
);
59 current
= current
->Flink
;
61 InsertTailList(&DeviceQueue
->ListHead
,&DeviceQueueEntry
->Entry
);
63 KeReleaseSpinLock(&DeviceQueue
->Lock
,oldlvl
);
67 PKDEVICE_QUEUE_ENTRY
KeRemoveByKeyDeviceQueue(PKDEVICE_QUEUE DeviceQueue
,
72 PKDEVICE_QUEUE_ENTRY entry
;
74 assert_irql(DISPATCH_LEVEL
);
75 assert(DeviceQueue
!=NULL
);
76 assert(DeviceQueue
->Busy
);
78 KeAcquireSpinLock(&DeviceQueue
->Lock
,&oldlvl
);
80 current
= DeviceQueue
->ListHead
.Flink
;
81 while (current
!= &DeviceQueue
->ListHead
)
83 entry
= CONTAINING_RECORD(current
,KDEVICE_QUEUE_ENTRY
,Entry
);
84 if (entry
->Key
< SortKey
||
85 current
->Flink
== &DeviceQueue
->ListHead
)
87 RemoveEntryList(current
);
88 KeReleaseSpinLock(&DeviceQueue
->Lock
,oldlvl
);
91 current
= current
->Flink
;
93 DeviceQueue
->Busy
= FALSE
;
94 KeReleaseSpinLock(&DeviceQueue
->Lock
, oldlvl
);
98 PKDEVICE_QUEUE_ENTRY
KeRemoveDeviceQueue(PKDEVICE_QUEUE DeviceQueue
)
100 * FUNCTION: Removes an entry from a device queue
102 * DeviceQueue = Queue to remove the entry
103 * RETURNS: The removed entry
107 PLIST_ENTRY list_entry
;
108 PKDEVICE_QUEUE_ENTRY entry
;
110 DPRINT("KeRemoveDeviceQueue(DeviceQueue %x)\n",DeviceQueue
);
112 assert_irql(DISPATCH_LEVEL
);
113 assert(DeviceQueue
!=NULL
);
114 assert(DeviceQueue
->Busy
);
116 KeAcquireSpinLock(&DeviceQueue
->Lock
,&oldlvl
);
118 list_entry
= RemoveHeadList(&DeviceQueue
->ListHead
);
119 if (list_entry
==(&DeviceQueue
->ListHead
))
121 DeviceQueue
->Busy
=FALSE
;
122 KeReleaseSpinLock(&DeviceQueue
->Lock
,oldlvl
);
125 KeReleaseSpinLock(&DeviceQueue
->Lock
,oldlvl
);
127 entry
= CONTAINING_RECORD(list_entry
,KDEVICE_QUEUE_ENTRY
,Entry
);
131 VOID
KeInitializeDeviceQueue(PKDEVICE_QUEUE DeviceQueue
)
133 * FUNCTION: Intializes a device queue
135 * DeviceQueue = Device queue to initialize
138 assert(DeviceQueue
!=NULL
);
139 InitializeListHead(&DeviceQueue
->ListHead
);
140 DeviceQueue
->Busy
=FALSE
;
141 KeInitializeSpinLock(&DeviceQueue
->Lock
);
144 BOOLEAN
KeInsertDeviceQueue(PKDEVICE_QUEUE DeviceQueue
,
145 PKDEVICE_QUEUE_ENTRY DeviceQueueEntry
)
147 * FUNCTION: Inserts an entry in a device queue
149 * DeviceQueue = Queue to insert the entry in
150 * DeviceQueueEntry = Entry to insert
151 * RETURNS: False is the device queue wasn't busy
157 KeAcquireSpinLock(&DeviceQueue
->Lock
,&oldlvl
);
159 if (!DeviceQueue
->Busy
)
161 DeviceQueue
->Busy
=TRUE
;
162 KeReleaseSpinLock(&DeviceQueue
->Lock
,oldlvl
);
166 InsertTailList(&DeviceQueue
->ListHead
,
167 &DeviceQueueEntry
->Entry
);
168 DeviceQueueEntry
->Key
=0;
170 KeReleaseSpinLock(&DeviceQueue
->Lock
,oldlvl
);