Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 | /* * Copyright (c) 2024 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. The rights granted to you under the License * may not be used to create, or enable the creation or redistribution of, * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ #ifndef IOGCCircularDataQueue_h #define IOGCCircularDataQueue_h #if KERNEL #include <IOKit/IOLib.h> #else #include <IOKit/IOKitLib.h> #endif __BEGIN_DECLS struct IOCircularDataQueue; typedef struct IOCircularDataQueue IOCircularDataQueue; // IOCircularDataQueueCreate* options typedef enum __OS_ENUM_ATTR IOCircularDataQueueCreateOptions { kIOCircularDataQueueCreateConsumer = 0x00000001, kIOCircularDataQueueCreateProducer = 0x00000002 } IOCircularDataQueueCreateOptions; #if KERNEL /*! * @function IOCircularDataQueueCreateWithEntries * @abstract Function that creates a new IOCircularDataQueue instance with the specified number of entries of the given * size. * @discussion This method will create a new IOCircularDataQueue instance with enough capacity for numEntries of * entrySize each. It does account for the IOCircularDataQueueEntryHeader overhead for each entry. Note that the * numEntries and entrySize are simply used to determine the data region size. They do not actually restrict the number * of enqueues to the queue since its a circular buffer and will eventually overwrite old data. At any time, the * allocated data region can hold a maximum of numEntries queue entries. <br> This method allocates a new * IOCircularDataQueue instance with the given numEntries and entrySize parameters. * @param options IOCircularDataQueueCreateOptions. * @param numEntries Number of entries to allocate space for. * @param entrySize Size of each entry. * @param pQueue Pointer to a queue handle. On return, this holds a handle to the newly allocated queue. * @return * - `kIOReturnSuccess` if the queue was succesfully intialized. * - `kIOReturnBadArgument` if the parameters passed were invalid. * - `kIOReturnNoMemory` if there was a memory allocation failure. */ IOReturn IOCircularDataQueueCreateWithEntries(IOCircularDataQueueCreateOptions options, uint32_t numEntries, uint32_t entrySize, IOCircularDataQueue **pQueue); /*! * @function IOCircularDataQueueCopyMemoryDescriptor * @abstract Returns a reference to the IOMemoryDescriptor for the queue's memory. * @discussion Returns a reference to the IOMemoryDescriptor for the queue's memory. * @param queue Queue handle. On return, this holds a handle to the newly allocated queue. * @return IOMemoryDescriptor reference */ IOMemoryDescriptor * IOCircularDataQueueCopyMemoryDescriptor(IOCircularDataQueue *queue); #else /* KERNEL */ /*! * @function IOCircularDataQueueCreateWithConnection * @abstract Function that creates a new IOCircularDataQueue instance with an open IOUserClient connection. * @discussion This method will create a new IOCircularDataQueue instance with a queue owned by the IOUserClient * instance passed in. The memory and queue attributes are created from the IOMemoryDescriptor returned by the IOUC * returned by clientMemoryForType() with the memoryType parameter passed to this function. This memory descriptor must * be one returned by the kernel api IOCircularDataQueueCopyMemoryDescriptor(). * @param options IOCircularDataQueueCreateOptions. * @param connect An open IOUserClient connection created by the caller with IOServiceOpen(). The connection must be * valid while the queue is in use. * @param memoryType memoryType argument that will passed to the IOUC clientMemoryForType() function to obtain the queue memory. * @param pQueue Pointer to a queue handle. On return, this holds a handle to the newly allocated queue. * @return * - `kIOReturnSuccess` if the queue was succesfully intialized. * - `kIOReturnBadArgument` if the parameters passed were invalid. * - `kIOReturnNoMemory` if there was a memory allocation failure. */ IOReturn IOCircularDataQueueCreateWithConnection(IOCircularDataQueueCreateOptions options, io_connect_t connect, uint32_t memoryType, IOCircularDataQueue **pQueue); #endif /* !KERNEL */ /*! * @function IOCircularDataQueueDestroy * @abstract Function that destroys a previously created IOCircularDataQueue instance (created with * IOCircularDataQueueCreateWithEntries). * @param pQueue Pointer to the queue handle. * @return * - `kIOReturnSuccess` if the queue was succesfully destroyed. * - `kIOReturnBadArgument` if an invalid queue was provided. */ IOReturn IOCircularDataQueueDestroy(IOCircularDataQueue **pQueue); /*! * @function IOCircularDataQueueEnqueue * @abstract Enqueues a new entry on the queue. * @discussion This method adds a new data entry of dataSize to the queue. It sets the size parameter of the entry * pointed to by the write index and copies the memory pointed to by the data parameter in place in the queue. Once * that is done, it moves the write index to the next index. * @param queue Handle to the queue. * @param data Pointer to the data to be added to the queue. * @param dataSize Size of the data pointed to by data. * @return * - `kIOReturnSuccess` on success. * - `kIOReturnBadMedia` if the queue shared memory has been compromised. * - `kIOReturnBadArgument` if an invalid queue was provided. * - `kIOReturnBusy` if another thread is enqueing concurrently * - `kIOReturnUnsupported` if the queue has not been configured to support fixed size entries. Variable size is * currently not supported * - Other values indicate an error. */ IOReturn IOCircularDataQueueEnqueue(IOCircularDataQueue *queue, const void *data, size_t dataSize); /*! * @function IOCircularDataQueueGetLatest * Access the latest entry data, also update the cursor position to the latest. No copy is made of the data. <br> Caller * is supposed to call IOCircularDataQueueIsCurrentDataValid() to check data integrity after reading the data is * complete. * @param queue Handle to the queue. * @param data A pointer to the data memory region for the latest entry data in the queue. * @param size A pointer to the size of the data parameter. On return, this contains the actual size of the data * pointed to by data param. * @return * - `kIOReturnSuccess` if the cursor position was updated. * - `kIOReturnUnderrun` if nothing has ever been enqueued into the queue * - `kIOReturnBadMedia` if the queue shared memory has been compromised. * - `kIOReturnBadArgument` if an invalid queue was provided. * - `kIOReturnTimeout` if the reader timed out when trying to read. This is possible if the writer overwrites the * latest index a reader is about to read. The function times out if the read is unsuccessful after multiple retries. * - Other values indicate an error. */ IOReturn IOCircularDataQueueGetLatest(IOCircularDataQueue *queue, void **data, size_t *size); /*! * @function IOCircularDataQueueCopyLatest * Access the latest entry data and copy into the provided buffer. Also update the cursor position to the latest. On a * successful return, the function gaurantees that the latest data was successfully copied. In this case there is no * need to call IOCircularDataQueueIsCurrentDataValid() after reading the data is complete, since the function returns a * copy which cannot be overwritten by the writer. * @param queue Handle to the queue. * @param data Pointer to memory into which the latest data from the queue is copied. Lifetime of this memory is * controlled by the caller. * @param size Size of the data buffer provided for copying. On return, this contains the actual size of the data * pointed to by data param. * @return * - `kIOReturnSuccess` if the cursor position was updated to latest and the data was successfully copied. * - `kIOReturnUnderrun` if nothing has ever been enqueued into the queue * - `kIOReturnBadArgument` if the buffer provided to copy the data is NULL or if an invalid queue was provided.. * - `kIOReturnBadMedia` if the queue shared memory has been compromised. * - `kIOReturnTimeout` if the reader timed out when trying to copy the latest data. This is possible if the writer * overwrites the latest index a reader is about to copy. The function times out if the copy is unsuccessful after * multiple retries. * - Other values indicate an error. * */ IOReturn IOCircularDataQueueCopyLatest(IOCircularDataQueue *queue, void *data, size_t *size); /*! * @function IOCircularDataQueueGetNext * Access the data at the next cursor position and updates the cursor position to the next. No copy is made of the data. * <br> Caller is supposed to call IOCircularDataQueueIsCurrentDataValid() to check data integrity after reading the * data is complete. * @param queue Handle to the queue. * @param data A pointer to the data memory region for the next entry data in the queue. * @param size A pointer to the size of the data parameter. On return, this contains the actual size of the data * pointed to by data param. * @return * - `kIOReturnSuccess` if the cursor position was updated to the latest. * - `kIOReturnAborted` if the cursor has become invalid, possibly due to a reset of the queue. * - `kIOReturnUnderrun` if the cursor has reached the latest available data. * - `kIOReturnOverrun` if the entry at the cursor position is no longer in * the queue's buffer. Call IOCircularDataQueueGetLatest to get the latest data and cursor position. * - `kIOReturnBadArgument` if an invalid argument is passsed. * - `kIOReturnBadMedia` if the queue shared memory has been compromised. * - Other values indicate an error. * */ IOReturn IOCircularDataQueueGetNext(IOCircularDataQueue *queue, void **data, size_t *size); /*! * @function IOCircularDataQueueCopyNext * Access the data at the next cursor position and copy into the provided buffer. Also update the cursor position to the * next. On a successful return, the function gaurantees that the next entry data was successfully copied. In this case * there is no need to call IOCircularDataQueueIsCurrentDataValid() after reading the data is complete, since the * function returns a copy which cannot be overwritten by the writer. * @param queue Handle to the queue. * @param data Pointer to memory into which the next data from the queue is copied. Lifetime of this memory is * controlled by the caller. * @param size Size of the data buffer provided for copying. On return, this contains the actual size of the data * pointed to by data param. * @return * - `kIOReturnSuccess` if the cursor position was updated to next and the data was successfully copied. * - `kIOReturnAborted` if the cursor has become invalid, possibly due to a reset of the queue. * - `kIOReturnUnderrun` if the cursor has reached the latest available data. * - `kIOReturnOverrun` if the entry at the cursor position is no longer in * the queue's buffer. Call IOCircularDataQueueCopyLatest to get the latest data and cursor position. * - `kIOReturnBadArgument` if an invalid argument is passsed. * - `kIOReturnBadMedia` if the queue shared memory has been compromised. * - Other values indicate an error. * */ IOReturn IOCircularDataQueueCopyNext(IOCircularDataQueue *queue, void *data, size_t *size); /*! * @function IOCircularDataQueueGetPrevious * Access the data at the previous cursor position and updates the cursor position to the previous. No copy is made of * the data. <br> Caller is supposed to call IOCircularDataQueueIsCurrentDataValid() to check data integrity after * reading the data is complete. * @param queue Handle to the queue. * @param data A pointer to the data memory region for the previous entry data in the queue. * @param size A pointer to the size of the data parameter. On return, this contains the actual size of the data * pointed to by data param. * @return * - `kIOReturnSuccess` if the cursor position was updated to the previous. * - `kIOReturnAborted` if the cursor has become invalid, possibly due to a reset of the queue. * - `kIOReturnOverrun` if the entry at the cursor position is no longer in * the queue's buffer. Call IOCircularDataQueueGetLatest to get the latest data and cursor position. * - `kIOReturnBadArgument` if an invalid argument is passsed. * - `kIOReturnBadMedia` if the queue shared memory has been compromised. * - Other values indicate an error. * */ IOReturn IOCircularDataQueueGetPrevious(IOCircularDataQueue *queue, void **data, size_t *size); /*! * @function IOCircularDataQueueCopyPrevious * Access the data at the previous cursor position and copy into the provided buffer. Also update the cursor position to * the previous. On a successful return, the function gaurantees that the previous entry data was successfully copied. * In this case there is no need to call IOCircularDataQueueIsCurrentDataValid() after reading the data is complete, * since the function returns a copy which cannot be overwritten by the writer. * @param queue Handle to the queue. * @param data Pointer to memory into which the previous data is copied. Lifetime of this memory is controlled by the * caller. * @param size Size of the data buffer provided for copying. On return, this contains the actual size of the data * pointed to by data param. * @return * - `kIOReturnSuccess` if the cursor position was updated to the previous and the data was successfully copied. * - `kIOReturnAborted` if the cursor has become invalid, possibly due to a reset of the queue. * - `kIOReturnOverrun` if the entry at the cursor position is no longer in * the queue's buffer. Call IOCircularDataQueueCopyLatest to get the latest data and cursor position. * - `kIOReturnBadArgument` if an invalid argument is passsed. * - `kIOReturnBadMedia` if the queue shared memory has been compromised. * - Other values indicate an error. * */ IOReturn IOCircularDataQueueCopyPrevious(IOCircularDataQueue *queue, void *data, size_t *size); /*! * @function IOCircularDataQueueIsCurrentDataValid * Verify if the data at the current cursor position is the same as the data when the cursor was first updated to this * position. Call this function after having read the data at the current cursor position from the queue, since the * queue entry could potentially have been overwritten by the writer while being read by the caller. <br> * @param queue Handle to the queue. * @return * - `kIOReturnSuccess` if the data at the cursor position is unchanged. * - `kIOReturnOverrun` if the entry at the cursor position is no longer the same and is * potentially overwritten. Call IOCircularDataQueueGetLatest to get the latest data and cursor position. * - `kIOReturnAborted` if the cursor has become invalid, possibly due to a reset of the queue. * - `kIOReturnBadArgument` if an invalid param was passed. * - `kIOReturnBadMedia` if the queueMemory is corrupted. * - Other values indicate an error. * */ IOReturn IOCircularDataQueueIsCurrentDataValid(IOCircularDataQueue *queue); /*! * @function IOCircularDataQueueSetCursorLatest * Set the current cursor position to the latest entry in the queue. This only updates the cursor and does not read the * data from the queue. If nothing has been enqueued into the queue yet, this returns an error. * @param queue Handle to the queue. * @return * - `kIOReturnSuccess` if the cursor position was updated to the latest. * - `kIOReturnUnderrun` if nothing has ever been enqueued into the queue since there is no latest entry. * - `kIOReturnAborted` if the queue is in an irrecoverable state. * - `kIOReturnBadArgument` if an invalid argument is passsed. * - `kIOReturnBadMedia` if the queue shared memory has been compromised. * - Other values indicate an error. * */ IOReturn IOCircularDataQueueSetCursorLatest(IOCircularDataQueue *queue); /*! * @function IOCircularDataQueueGetCurrent * Access the data at the current cursor position. The cursor position is unchanged. No copy is made of the data. <br> * Caller is supposed to call IOCircularDataQueueIsCurrentDataValid() to check data integrity after reading the data is * complete. * @param queue Handle to the queue. * @param data A pointer to the data memory region for the next entry data in the queue. * @param size A pointer to the size of the data parameter. On return, this contains the actual size of the data * pointed to by data param. * @return * - `kIOReturnSuccess` if the cursor position was updated. * - `kIOReturnAborted` if the cursor has become invalid, possibly due to a reset of the queue. * - `kIOReturnUnderrun` if nothing has ever been enqueued into the queue hence there is no entry at the current * position.. * - `kIOReturnOverrun` if the entry at the current cursor position is no longer in * the queue's buffer. Call IOCircularDataQueueGetLatest to get the latest data and cursor position. * - `kIOReturnBadArgument` if an invalid argument is passsed. * - `kIOReturnBadMedia` if the queue shared memory has been compromised. * - Other values indicate an error. * */ IOReturn IOCircularDataQueueGetCurrent(IOCircularDataQueue *queue, void **data, size_t *size); /*! * @function IOCircularDataQueueCopyCurrent * Access the data at the current cursor position and copy into the provided buffer. The cursor position is unchanged. * If successful, function gaurantees that the data returned is always valid, hence no need to call * IOCircularDataQueueIsCurrentDataValid(). * @param queue Handle to the queue. * @param data Pointer to memory into which the previous data is copied. Lifetime of this memory is controlled by the * caller. * @param size Size of the data buffer provided for copying. On return, this contains the actual size of the data * pointed to by data param. * @return * - `kIOReturnSuccess` if the cursor position was updated. * - `kIOReturnAborted` if the cursor has become invalid, possibly due to a reset of the queue. * - `kIOReturnUnderrun` if nothing has ever been enqueued into the queue hence there is no entry at the current * position.. * - `kIOReturnOverrun` if the entry at the current cursor position is no longer in * the queue's buffer. Call IOCircularDataQueueCopyLatest to get the latest data and cursor position. * - `kIOReturnBadArgument` if an invalid argument is passsed. * - `kIOReturnBadMedia` if the queue shared memory has been compromised. * - Other values indicate an error. * */ IOReturn IOCircularDataQueueCopyCurrent(IOCircularDataQueue *queue, void *data, size_t *size); /*! * @function IOCircularDataQueueGetLatestWithBlock * Access the latest entry data, also update the cursor position to the latest. Calls the provided block with the data * at the cursor position. No copy is made of the data. <br> Optionally the caller can call * IOCircularDataQueueIsCurrentDataValid() to check data integrity after reading the data is complete in the block. * Additionally the function also returns an error if the data has been overwritten after the block completion * @param queue Handle to the queue. * @param handler Block to call * -param data Pointer to the latest data in the queue that the block is called with. * -param size Size of the data pointed to by data that the block is called with. * @return * - `kIOReturnSuccess` if the cursor position was updated to the latest. * - `kIOReturnUnderrun` if nothing has ever been enqueued into the queue * - `kIOReturnBadMedia` if the queue shared memory has been compromised. * - `kIOReturnBadArgument` if an invalid queue was provided. * - `kIOReturnAborted` if the queue was reset. * - Other values indicate an error. * */ IOReturn IOCircularDataQueueGetLatestWithBlock(IOCircularDataQueue * queue, void (^handler)(const void *data, size_t size)); /*! * @function IOCircularDataQueueGetNextWithBlock * Access the data at the next cursor position and updates the cursor position to the next. Calls the provided block * with the data at the cursor position. No copy is made of the data. <br> Optionally the caller can call * IOCircularDataQueueIsCurrentDataValid() to check data integrity after reading the data is complete in the block. * Additionally the function also returns an error if the data has been overwritten after the block completion. * @param queue Handle to the queue. * @param handler Block to call * -param data A pointer to the data memory region for the next entry data in the queue that the block is called with. * -param size Size of the data pointed to by data that the block is called with. * @return * - `kIOReturnSuccess` if the cursor position was updated to next. * - `kIOReturnAborted` if the cursor has become invalid, possibly due to a reset of the queue. * - `kIOReturnUnderrun` if the cursor has reached the latest available data. * - `kIOReturnOverrun` if the entry at the cursor position is no longer in * the queue's buffer. Call IOCircularDataQueueGetLatest to get the latest data and cursor position. * - `kIOReturnBadArgument` if an invalid argument is passsed. * - `kIOReturnBadMedia` if the queue shared memory has been compromised. * - Other values indicate an error. * */ IOReturn IOCircularDataQueueGetNextWithBlock(IOCircularDataQueue * queue, void (^handler)(const void *data, size_t size)); /*! * @function IOCircularDataQueueGetPreviousWithBlock * Access the data at the previous cursor position and updates the cursor position to the previous. Calls the provided * block with the data at the cursor position. No copy is made of the data. <br> Optionally the caller can call * IOCircularDataQueueIsCurrentDataValid() to check data integrity after reading the data is complete in the block. * Additionally the function also returns an error if the data has been overwritten after the block completion. * @param queue Handle to the queue. * @param handler Block to call * -param data A pointer to the data memory region for the previous entry data in the queue that the block is called * with. * -param size Size of the data pointed to by data that the block is called with. * @return * - `kIOReturnSuccess` if the cursor position was updated to previous. * - `kIOReturnAborted` if the cursor has become invalid, possibly due to a reset of the queue. * - `kIOReturnUnderrun` if the entry at the cursor position is no longer in * the queue's buffer. Call IOCircularDataQueueGetLatest to get the latest data and cursor position. * - `kIOReturnBadArgument` if an invalid argument is passsed. * - `kIOReturnBadMedia` if the queue shared memory has been compromised. * - Other values indicate an error. * */ IOReturn IOCircularDataQueueGetPreviousWithBlock(IOCircularDataQueue * queue, void (^handler)(const void *data, size_t size)); __END_DECLS #endif /* IOGCCircularDataQueue_h */ |