Mercurial > games > semicongine
comparison fuhtark_test/include/ddk/csq.h @ 1500:91c8c3b7cbf0
add: futhark tests for generating vulkan api
| author | sam <sam@basx.dev> |
|---|---|
| date | Wed, 26 Nov 2025 21:36:48 +0700 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1499:1f58458b7ef7 | 1500:91c8c3b7cbf0 |
|---|---|
| 1 /* | |
| 2 * Cancel-Safe Queue Library | |
| 3 * Copyright (c) 2004, Vizzini (vizzini@plasmic.com) | |
| 4 * Licensed under the GNU GPL for the ReactOS project | |
| 5 * | |
| 6 * This header defines the interface to the ReactOS Cancel-Safe Queue library. | |
| 7 * This interface is based on and is similar to the Microsoft Cancel-Safe | |
| 8 * Queue interface. | |
| 9 * | |
| 10 * BACKGROUND | |
| 11 * | |
| 12 * IRP queuing is a royal pain in the butt, due to the fact that there are | |
| 13 * tons of built-in race conditions. IRP handling is difficult in general, | |
| 14 * but the cancel logic has been particularly complicated due to some subtle | |
| 15 * races, coupled with the fact that the system interfaces have changed over | |
| 16 * time. | |
| 17 * | |
| 18 * Walter Oney (2nd. Ed. of Programming the Windows Driver Model) states a | |
| 19 * common opinion among driver developers when he says that it is foolish | |
| 20 * to try to roll your own cancel logic. There are only a very few people | |
| 21 * who have gotten it right in the past. He suggests, instead, that you | |
| 22 * either use his own well-tested code, or use the code in the Microsoft | |
| 23 * Cancel-Safe Queue Library. | |
| 24 * | |
| 25 * We cannot do either, of course, due to copyright issues. I have therefore | |
| 26 * created this clone of the Microsoft library in order to concentrate all | |
| 27 * of the IRP-queuing bugs in one place. I'm quite sure there are problems | |
| 28 * here, so if you are a driver writer, I'd be glad to hear your feedback. | |
| 29 * | |
| 30 * Apart from that, please try to use these routines, rather than building | |
| 31 * your own. If you think you have found a bug, please bring it up with me | |
| 32 * or on-list, as this is complicated and non-obvious stuff. Don't just | |
| 33 * change this and hope for the best! | |
| 34 * | |
| 35 * USAGE | |
| 36 * | |
| 37 * This library follows exactly the same interface as the Microsoft Cancel-Safe | |
| 38 * Queue routines (IoCsqXxx()). As such, the authoritative reference is the | |
| 39 * current DDK. There is also a DDK sample called "cancel" that has an | |
| 40 * example of how to use this code. I have also provided a sample driver | |
| 41 * that makes use of this queue. Finally, please do read the header and the | |
| 42 * source if you're curious about the inner workings of these routines. | |
| 43 */ | |
| 44 | |
| 45 #ifndef _REACTOS_CSQ_H | |
| 46 #define _REACTOS_CSQ_H | |
| 47 | |
| 48 /* | |
| 49 * Prevent including the CSQ definitions twice. They're present in NTDDK | |
| 50 * now too, except the *_EX versions. | |
| 51 */ | |
| 52 #ifndef IO_TYPE_CSQ_IRP_CONTEXT | |
| 53 | |
| 54 struct _IO_CSQ; | |
| 55 | |
| 56 | |
| 57 /* | |
| 58 * CSQ Callbacks | |
| 59 * | |
| 60 * The cancel-safe queue is implemented as a set of IoCsqXxx() OS routines | |
| 61 * copuled with a set of driver callbacks to handle the basic operations of | |
| 62 * the queue. You need to supply one of each of these functions in your own | |
| 63 * driver. These routines are also documented in the DDK under CsqXxx(). | |
| 64 * That is the authoritative documentation. | |
| 65 */ | |
| 66 | |
| 67 /* | |
| 68 * Function to insert an IRP in the queue. No need to worry about locking; | |
| 69 * just tack it onto your list or something. | |
| 70 * | |
| 71 * Sample implementation: | |
| 72 * | |
| 73 VOID NTAPI CsqInsertIrp(PIO_CSQ Csq, PIRP Irp) | |
| 74 { | |
| 75 KdPrint(("Inserting IRP 0x%x into CSQ\n", Irp)); | |
| 76 InsertTailList(&IrpQueue, &Irp->Tail.Overlay.ListEntry); | |
| 77 } | |
| 78 * | |
| 79 */ | |
| 80 typedef VOID (NTAPI *PIO_CSQ_INSERT_IRP) (struct _IO_CSQ *Csq, | |
| 81 PIRP Irp); | |
| 82 | |
| 83 | |
| 84 /* | |
| 85 * Function to remove an IRP from the queue. | |
| 86 * | |
| 87 * Sample: | |
| 88 * | |
| 89 VOID NTAPI CsqRemoveIrp(PIO_CSQ Csq, PIRP Irp) | |
| 90 { | |
| 91 KdPrint(("Removing IRP 0x%x from CSQ\n", Irp)); | |
| 92 RemoveEntryList(&Irp->Tail.Overlay.ListEntry); | |
| 93 } | |
| 94 * | |
| 95 */ | |
| 96 typedef VOID (NTAPI *PIO_CSQ_REMOVE_IRP) (struct _IO_CSQ *Csq, | |
| 97 PIRP Irp); | |
| 98 | |
| 99 /* | |
| 100 * Function to look for an IRP in the queue | |
| 101 * | |
| 102 * Sample: | |
| 103 * | |
| 104 PIRP NTAPI CsqPeekNextIrp(PIO_CSQ Csq, PIRP Irp, PVOID PeekContext) | |
| 105 { | |
| 106 KdPrint(("Peeking for next IRP\n")); | |
| 107 | |
| 108 if(Irp) | |
| 109 return CONTAINING_RECORD(&Irp->Tail.Overlay.ListEntry.Flink, IRP, Tail.Overlay.ListEntry); | |
| 110 | |
| 111 if(IsListEmpty(&IrpQueue)) | |
| 112 return NULL; | |
| 113 | |
| 114 return CONTAINING_RECORD(IrpQueue.Flink, IRP, Tail.Overlay.ListEntry); | |
| 115 } | |
| 116 * | |
| 117 */ | |
| 118 typedef PIRP (NTAPI *PIO_CSQ_PEEK_NEXT_IRP) (struct _IO_CSQ *Csq, | |
| 119 PIRP Irp, | |
| 120 PVOID PeekContext); | |
| 121 | |
| 122 /* | |
| 123 * Lock the queue. This can be a spinlock, a mutex, or whatever | |
| 124 * else floats your boat. | |
| 125 * | |
| 126 * Sample: | |
| 127 * | |
| 128 VOID NTAPI CsqAcquireLock(PIO_CSQ Csq, PKIRQL Irql) | |
| 129 { | |
| 130 KdPrint(("Acquiring spin lock\n")); | |
| 131 KeAcquireSpinLock(&IrpQueueLock, Irql); | |
| 132 } | |
| 133 * | |
| 134 */ | |
| 135 typedef VOID (NTAPI *PIO_CSQ_ACQUIRE_LOCK) (struct _IO_CSQ *Csq, | |
| 136 PKIRQL Irql); | |
| 137 | |
| 138 /* | |
| 139 * Unlock the queue: | |
| 140 * | |
| 141 VOID NTAPI CsqReleaseLock(PIO_CSQ Csq, KIRQL Irql) | |
| 142 { | |
| 143 KdPrint(("Releasing spin lock\n")); | |
| 144 KeReleaseSpinLock(&IrpQueueLock, Irql); | |
| 145 } | |
| 146 * | |
| 147 */ | |
| 148 typedef VOID (NTAPI *PIO_CSQ_RELEASE_LOCK) (struct _IO_CSQ *Csq, | |
| 149 KIRQL Irql); | |
| 150 | |
| 151 /* | |
| 152 * Finally, this is called by the queue library when it wants to complete | |
| 153 * a canceled IRP. | |
| 154 * | |
| 155 * Sample: | |
| 156 * | |
| 157 VOID NTAPI CsqCompleteCancelledIrp(PIO_CSQ Csq, PIRP Irp) | |
| 158 { | |
| 159 KdPrint(("cancelling irp 0x%x\n", Irp)); | |
| 160 Irp->IoStatus.Status = STATUS_CANCELLED; | |
| 161 Irp->IoStatus.Information = 0; | |
| 162 IoCompleteRequest(Irp, IO_NO_INCREMENT); | |
| 163 } | |
| 164 * | |
| 165 */ | |
| 166 typedef VOID (NTAPI *PIO_CSQ_COMPLETE_CANCELED_IRP) (struct _IO_CSQ *Csq, | |
| 167 PIRP Irp); | |
| 168 | |
| 169 | |
| 170 /* | |
| 171 * STRUCTURES | |
| 172 * | |
| 173 * NOTE: Please do not use these directly. You will make incompatible code | |
| 174 * if you do. Always only use the documented IoCsqXxx() interfaces and you | |
| 175 * will amass much Good Karma. | |
| 176 */ | |
| 177 #define IO_TYPE_CSQ_IRP_CONTEXT 1 | |
| 178 #define IO_TYPE_CSQ 2 | |
| 179 | |
| 180 /* | |
| 181 * IO_CSQ - Queue control structure | |
| 182 */ | |
| 183 typedef struct _IO_CSQ { | |
| 184 ULONG Type; | |
| 185 PIO_CSQ_INSERT_IRP CsqInsertIrp; | |
| 186 PIO_CSQ_REMOVE_IRP CsqRemoveIrp; | |
| 187 PIO_CSQ_PEEK_NEXT_IRP CsqPeekNextIrp; | |
| 188 PIO_CSQ_ACQUIRE_LOCK CsqAcquireLock; | |
| 189 PIO_CSQ_RELEASE_LOCK CsqReleaseLock; | |
| 190 PIO_CSQ_COMPLETE_CANCELED_IRP CsqCompleteCanceledIrp; | |
| 191 PVOID ReservePointer; /* must be NULL */ | |
| 192 } IO_CSQ, *PIO_CSQ; | |
| 193 | |
| 194 /* | |
| 195 * IO_CSQ_IRP_CONTEXT - Context used to track an IRP in the CSQ | |
| 196 */ | |
| 197 typedef struct _IO_CSQ_IRP_CONTEXT { | |
| 198 ULONG Type; | |
| 199 PIRP Irp; | |
| 200 PIO_CSQ Csq; | |
| 201 } IO_CSQ_IRP_CONTEXT, *PIO_CSQ_IRP_CONTEXT; | |
| 202 | |
| 203 #endif /* IO_TYPE_CSQ_IRP_CONTEXT */ | |
| 204 | |
| 205 /* See IO_TYPE_CSQ_* above */ | |
| 206 #define IO_TYPE_CSQ_EX 3 | |
| 207 | |
| 208 /* | |
| 209 * Function to insert an IRP into the queue with extended context information. | |
| 210 * This is useful if you need to be able to de-queue particular IRPs more | |
| 211 * easily in some cases. | |
| 212 * | |
| 213 * Same deal as above; sample implementation: | |
| 214 * | |
| 215 NTSTATUS NTAPI CsqInsertIrpEx(PIO_CSQ Csq, PIRP Irp, PVOID InsertContext) | |
| 216 { | |
| 217 CsqInsertIrp(Csq, Irp); | |
| 218 return STATUS_PENDING; | |
| 219 } | |
| 220 * | |
| 221 */ | |
| 222 typedef NTSTATUS (NTAPI *PIO_CSQ_INSERT_IRP_EX) (struct _IO_CSQ *Csq, | |
| 223 PIRP Irp, | |
| 224 PVOID InsertContext); | |
| 225 | |
| 226 /* | |
| 227 * CANCEL-SAFE QUEUE DDIs | |
| 228 * | |
| 229 * These device driver interfaces are called to make use of the queue. Again, | |
| 230 * authoritative documentation for these functions is in the DDK. The csqtest | |
| 231 * driver also makes use of some of them. | |
| 232 */ | |
| 233 | |
| 234 | |
| 235 /* | |
| 236 * Call this in DriverEntry or similar in order to set up the Csq structure. | |
| 237 * As long as the Csq struct and the functions you pass in are resident, | |
| 238 * there are no IRQL restrictions. | |
| 239 */ | |
| 240 NTKERNELAPI | |
| 241 NTSTATUS NTAPI IoCsqInitialize(PIO_CSQ Csq, | |
| 242 PIO_CSQ_INSERT_IRP CsqInsertIrp, | |
| 243 PIO_CSQ_REMOVE_IRP CsqRemoveIrp, | |
| 244 PIO_CSQ_PEEK_NEXT_IRP CsqPeekNextIrp, | |
| 245 PIO_CSQ_ACQUIRE_LOCK CsqAcquireLock, | |
| 246 PIO_CSQ_RELEASE_LOCK CsqReleaseLock, | |
| 247 PIO_CSQ_COMPLETE_CANCELED_IRP CsqCompleteCanceledIrp); | |
| 248 | |
| 249 /* | |
| 250 * Same as above, except you provide a CsqInsertIrpEx routine instead of | |
| 251 * CsqInsertIrp. This eventually allows you to supply extra tracking | |
| 252 * information for use with the queue. | |
| 253 */ | |
| 254 NTKERNELAPI | |
| 255 NTSTATUS NTAPI IoCsqInitializeEx(PIO_CSQ Csq, | |
| 256 PIO_CSQ_INSERT_IRP_EX CsqInsertIrpEx, | |
| 257 PIO_CSQ_REMOVE_IRP CsqRemoveIrp, | |
| 258 PIO_CSQ_PEEK_NEXT_IRP CsqPeekNextIrp, | |
| 259 PIO_CSQ_ACQUIRE_LOCK CsqAcquireLock, | |
| 260 PIO_CSQ_RELEASE_LOCK CsqReleaseLock, | |
| 261 PIO_CSQ_COMPLETE_CANCELED_IRP CsqCompleteCanceledIrp); | |
| 262 | |
| 263 /* | |
| 264 * Insert an IRP into the queue | |
| 265 */ | |
| 266 NTKERNELAPI | |
| 267 VOID NTAPI IoCsqInsertIrp(PIO_CSQ Csq, | |
| 268 PIRP Irp, | |
| 269 PIO_CSQ_IRP_CONTEXT Context); | |
| 270 | |
| 271 /* | |
| 272 * Insert an IRP into the queue, with special context maintained that | |
| 273 * makes it easy to find IRPs in the queue | |
| 274 */ | |
| 275 NTKERNELAPI | |
| 276 NTSTATUS NTAPI IoCsqInsertIrpEx(PIO_CSQ Csq, | |
| 277 PIRP Irp, | |
| 278 PIO_CSQ_IRP_CONTEXT Context, | |
| 279 PVOID InsertContext); | |
| 280 | |
| 281 /* | |
| 282 * Remove a particular IRP from the queue | |
| 283 */ | |
| 284 NTKERNELAPI | |
| 285 PIRP NTAPI IoCsqRemoveIrp(PIO_CSQ Csq, | |
| 286 PIO_CSQ_IRP_CONTEXT Context); | |
| 287 | |
| 288 /* | |
| 289 * Remove the next IRP from the queue | |
| 290 */ | |
| 291 NTKERNELAPI | |
| 292 PIRP NTAPI IoCsqRemoveNextIrp(PIO_CSQ Csq, | |
| 293 PVOID PeekContext); | |
| 294 | |
| 295 #endif /* _REACTOS_CSQ_H */ |
