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 | /* * Copyright (c) 2019-2019 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 _IOKIT_UIODISPATCHQUEUE_H #define _IOKIT_UIODISPATCHQUEUE_H #include <DriverKit/OSObject.iig> #include <DriverKit/OSAction.iig> #include <DriverKit/IODispatchSource.iig> typedef int (*IODispatchLogFunction)(const char *format, ...); typedef void (^IODispatchBlock)(void); typedef void (*IODispatchFunction)(void * context); typedef kern_return_t (^IODispatchAction)(void); typedef void (^IODispatchQueueCancelHandler)(void); // options for Create() enum { kIODispatchQueueReentrant = 0x00000001, kIODispatchQueueMethodsNotSynchronized = 0x00000002, }; // options for WakeupWithOptions() enum { kIODispatchQueueWakeupAll = 0x00000001, }; // options for SleepWithDeadline() enum { // Sleep on an event which other threads are still waiting on, but has already been signaled kIODispatchQueueSleepReuseEvent = 0x00000100, }; /*! * @class IODispatchQueue * * @abstract * IODispatchQueue provides a queue for ordered execution of blocks. * * @discussion * All blocks submitted to dispatch queues are dequeued in FIFO order. * By default the queue is serial and will execute one block at a time. */ class NATIVE KERNEL IODispatchQueue : public OSObject { public: /*! * @brief Creates a new dispatch queue object. * @discussion Creates a new dispatch queue object. All queues are currently serial, executing one block at time * FIFO order. The new object has retain count 1 and should be released by the caller. * @param options kIODispatchQueueReentrant Creates a queue that allows release with the Sleep method, so that other threads and callers may acquire the queue. * @param priority No priorities are currently defined, pass zero. * @return kIOReturnSuccess on success. See IOReturn.h for error codes. */ static kern_return_t Create( const IODispatchQueueName name, uint64_t options, uint64_t priority, IODispatchQueue ** queue) LOCAL; virtual bool init() override; virtual void free() override; /*! * @brief Determines if the current thread is running on the queue. * @discussion Determines if the current thread is running on the queue, including if the queue invoked a * second queue (ie. OnQueue can return true for more than one queue in a given context.) * @return bool true if current thread is running on this queue. */ bool OnQueue() LOCALONLY; /*! * @brief Return the name the queue was created with. * @discussion Returns a pointer to the queues name. Only valid while the queue is retained. * @return C-string pointer in the queues internal storage. */ const char * GetName() LOCALONLY; /*! * @brief Stop the queue from executing futher work. * @discussion Stops the queue from dequeuing work, and on completion of any block currently being executed, * invokes a callback block. Canceling is asynchronous. * @param handler Block that will executed when the queue has completed any inflight work * and will not execute further work. * @return C-string pointer in the queues internal storage. */ kern_return_t Cancel(IODispatchQueueCancelHandler handler) LOCALONLY; /*! * @brief Schedule a block to be executed on the queue asynchronously. * @discussion Schedules work to be done on the queue without waiting for it to complete. The queue will be * retained until the block completes. * @param block Block that will executed on the queue, not in the context of the caller. */ void DispatchAsync(IODispatchBlock block) LOCALONLY; /*! * @brief C-function callback version of DispatchAsync. */ void DispatchAsync_f(void * context, IODispatchFunction function) LOCALONLY; /*! * @brief Schedule a block to be executed concurrently & asynchronously. * @discussion Schedules work to be done on the queue without waiting for it to complete, and * concurrently with other blocks executed with DispatchConcurrent. The queue will be * retained until the block completes. May only be used with a queue created with * the kIODispatchQueueReentrant option. * @param block Block that will executed on the queue, not in the context of the caller. */ void DispatchConcurrent(IODispatchBlock block) LOCALONLY; /*! * @brief C-function callback version of DispatchConcurrent. */ void DispatchConcurrent_f(void * context, IODispatchFunction function) LOCALONLY; /*! * @brief Execute a block on the queue synchronously. * @discussion Execute a block on the queue synchronously. * @param block Block that will executed on the queue. */ void DispatchSync(IODispatchBlock block) LOCALONLY; /*! * @brief C-function callback version of DispatchSync. */ void DispatchSync_f(void * context, IODispatchFunction function) LOCALONLY; /*! * @brief Log the current execution context with respect to any queues the current thread holds. * @param output printf like output function. The address of IOLog is suitable to be used. */ static void Log(const char * message, IODispatchLogFunction output) LOCALONLY; /*! * @brief Version of DispatchSync that returns a kern_return_t status. */ kern_return_t RunAction(IODispatchAction action) LOCALONLY; /*! * @brief Put a thread that is currently running the queue to sleep, releasing the queue. * @discussion Put a thread to sleep waiting for an event but release the queue first. * In all cases (signal, timeout or error), the caller resumes running on the queue. * The caller must be currently running on the queue to call Sleep(). * @param event A unique token matching one later passed to Wakeup(). * @param options Pass one of the kIOTimerClock* options to specify the timebase for the * deadline, or zero for no timeout. * @param deadline Clock deadline to timeout the sleep. * @return kIOReturnSuccess or kIOReturnTimeout */ kern_return_t SleepWithDeadline(void * event, uint64_t options, uint64_t deadline) LOCALONLY; /*! * @brief Put a thread that is currently running the queue to sleep, releasing the queue. * @discussion Put a thread to sleep waiting for an event but release the queue first. * In all cases (signal, timeout or error), the caller resumes running on the queue. * The caller must be currently running on the queue to call Sleep(). * @param event A unique token matching one later passed to Wakeup(). * @param timeout Clock delay to timeout the sleep. * @return kIOReturnSuccess or kIOReturnTimeout */ kern_return_t SleepWithTimeout(void * event, uint64_t timeout) LOCALONLY; /*! * @brief Synonym for SleepWithTimeout() */ kern_return_t Sleep(void * event, uint64_t timeout) LOCALONLY; /*! * @brief Wakes a thread that is blocked in Sleep(). * @discussion Signals a thread that gave up the queue with Sleep() to continue running. * The caller must be currently running on the queue. * @param event A unique token matching one passed to Sleep(). * @return kIOReturnSuccess on success. See IOReturn.h for error codes. */ kern_return_t Wakeup(void * event) LOCALONLY; /*! * @brief Wakes a thread that is blocked in Sleep(). * @discussion Signals a thread that gave up the queue with Sleep() to continue running. * The caller must be currently running on the queue. * @param event A unique token matching one passed to Sleep(). * @param options kIODispatchQueueWakeupAll wake all threads waiting in Sleep(). The default is to wake only one of any waiting threads. * @return kIOReturnSuccess on success. See IOReturn.h for error codes. */ kern_return_t WakeupWithOptions(void * event, uint64_t options) LOCALONLY; }; #if DRIVERKIT_PRIVATE class EXTENDS (IODispatchQueue) IODispatchQueuePrivate { virtual kern_return_t SetPort( mach_port_t port PORTMAKESEND); }; #endif #endif /* ! _IOKIT_UIODISPATCH_H */ |