1*fdd8201dSApple OSS Distributions /* 2*fdd8201dSApple OSS Distributions * Copyright (c) 1998-2019 Apple Inc. All rights reserved. 3*fdd8201dSApple OSS Distributions * 4*fdd8201dSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5*fdd8201dSApple OSS Distributions * 6*fdd8201dSApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code 7*fdd8201dSApple OSS Distributions * as defined in and that are subject to the Apple Public Source License 8*fdd8201dSApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in 9*fdd8201dSApple OSS Distributions * compliance with the License. The rights granted to you under the License 10*fdd8201dSApple OSS Distributions * may not be used to create, or enable the creation or redistribution of, 11*fdd8201dSApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to 12*fdd8201dSApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any 13*fdd8201dSApple OSS Distributions * terms of an Apple operating system software license agreement. 14*fdd8201dSApple OSS Distributions * 15*fdd8201dSApple OSS Distributions * Please obtain a copy of the License at 16*fdd8201dSApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file. 17*fdd8201dSApple OSS Distributions * 18*fdd8201dSApple OSS Distributions * The Original Code and all software distributed under the License are 19*fdd8201dSApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20*fdd8201dSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21*fdd8201dSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22*fdd8201dSApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23*fdd8201dSApple OSS Distributions * Please see the License for the specific language governing rights and 24*fdd8201dSApple OSS Distributions * limitations under the License. 25*fdd8201dSApple OSS Distributions * 26*fdd8201dSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27*fdd8201dSApple OSS Distributions */ 28*fdd8201dSApple OSS Distributions 29*fdd8201dSApple OSS Distributions #ifndef __IOKIT_IOWORKLOOP_H 30*fdd8201dSApple OSS Distributions #define __IOKIT_IOWORKLOOP_H 31*fdd8201dSApple OSS Distributions 32*fdd8201dSApple OSS Distributions #include <libkern/c++/OSObject.h> 33*fdd8201dSApple OSS Distributions #include <IOKit/IOReturn.h> 34*fdd8201dSApple OSS Distributions #include <IOKit/IOLib.h> 35*fdd8201dSApple OSS Distributions #include <IOKit/IOLocks.h> 36*fdd8201dSApple OSS Distributions #include <libkern/c++/OSPtr.h> 37*fdd8201dSApple OSS Distributions 38*fdd8201dSApple OSS Distributions #include <IOKit/system.h> 39*fdd8201dSApple OSS Distributions 40*fdd8201dSApple OSS Distributions #if IOKITSTATS 41*fdd8201dSApple OSS Distributions #include <IOKit/IOStatisticsPrivate.h> 42*fdd8201dSApple OSS Distributions #endif 43*fdd8201dSApple OSS Distributions 44*fdd8201dSApple OSS Distributions class IOEventSource; 45*fdd8201dSApple OSS Distributions class IOTimerEventSource; 46*fdd8201dSApple OSS Distributions class IOCommandGate; 47*fdd8201dSApple OSS Distributions 48*fdd8201dSApple OSS Distributions /*! @class IOWorkLoop 49*fdd8201dSApple OSS Distributions * @discussion An IOWorkLoop is a thread of control that is intended to be used to provide single threaded access to hardware. This class has no knowledge of the nature and type of the events that it marshals and forwards. When a device driver successfully starts (see IOService::start), it is expected to create the event sources it will need to receive events. Then a work loop is initialized and the events are added to the work loop for monitoring. In general this set up will be automated by the family superclass of the specific device. 50*fdd8201dSApple OSS Distributions * <br><br> 51*fdd8201dSApple OSS Distributions * The thread main method walks the event source linked list and messages each one requesting a work check. At this point each event source is expected to notify its registered owner that the event has occurred. After each event has been walked and each indicates that another loop isn't required (by setting the 'more' flag to false) the thread will go to sleep on a signaling semaphore. 52*fdd8201dSApple OSS Distributions * <br><br> 53*fdd8201dSApple OSS Distributions * When an event source is registered with a work loop it is informed of the semaphore to use to wake up the loop. 54*fdd8201dSApple OSS Distributions */ 55*fdd8201dSApple OSS Distributions class IOWorkLoop : public OSObject 56*fdd8201dSApple OSS Distributions { 57*fdd8201dSApple OSS Distributions OSDeclareDefaultStructors(IOWorkLoop); 58*fdd8201dSApple OSS Distributions 59*fdd8201dSApple OSS Distributions public: 60*fdd8201dSApple OSS Distributions /*! 61*fdd8201dSApple OSS Distributions * @typedef Action 62*fdd8201dSApple OSS Distributions * @discussion Type and arguments of callout C function that is used when 63*fdd8201dSApple OSS Distributions * a runCommand is executed by a client. Cast to this type when you want a C++ 64*fdd8201dSApple OSS Distributions * member function to be used. Note the arg1 - arg3 parameters are straight pass 65*fdd8201dSApple OSS Distributions * through from the runCommand to the action callout. 66*fdd8201dSApple OSS Distributions * @param target 67*fdd8201dSApple OSS Distributions * Target of the function, can be used as a refcon. Note if a C++ function 68*fdd8201dSApple OSS Distributions * was specified, this parameter is implicitly the first parameter in the target 69*fdd8201dSApple OSS Distributions * member function's parameter list. 70*fdd8201dSApple OSS Distributions * @param arg0 Argument to action from run operation. 71*fdd8201dSApple OSS Distributions * @param arg1 Argument to action from run operation. 72*fdd8201dSApple OSS Distributions * @param arg2 Argument to action from run operation. 73*fdd8201dSApple OSS Distributions * @param arg3 Argument to action from run operation. 74*fdd8201dSApple OSS Distributions */ 75*fdd8201dSApple OSS Distributions typedef IOReturn (*Action)(OSObject *target, 76*fdd8201dSApple OSS Distributions void *arg0, void *arg1, 77*fdd8201dSApple OSS Distributions void *arg2, void *arg3); 78*fdd8201dSApple OSS Distributions 79*fdd8201dSApple OSS Distributions #ifdef __BLOCKS__ 80*fdd8201dSApple OSS Distributions typedef IOReturn (^ActionBlock)(); 81*fdd8201dSApple OSS Distributions #endif /* __BLOCKS__ */ 82*fdd8201dSApple OSS Distributions 83*fdd8201dSApple OSS Distributions enum { 84*fdd8201dSApple OSS Distributions kPreciousStack = 0x00000001, 85*fdd8201dSApple OSS Distributions kTimeLockPanics = 0x00000002, 86*fdd8201dSApple OSS Distributions }; 87*fdd8201dSApple OSS Distributions 88*fdd8201dSApple OSS Distributions private: 89*fdd8201dSApple OSS Distributions /*! @function threadMainContinuation 90*fdd8201dSApple OSS Distributions * @abstract Static function that calls the threadMain function. 91*fdd8201dSApple OSS Distributions */ 92*fdd8201dSApple OSS Distributions static void threadMainContinuation(IOWorkLoop *self); 93*fdd8201dSApple OSS Distributions 94*fdd8201dSApple OSS Distributions /*! @function eventSourcePerformsWork 95*fdd8201dSApple OSS Distributions * @abstract Checks if the event source passed in overrides checkForWork() to perform any work. 96*fdd8201dSApple OSS Distributions * IOWorkLoop uses this to determine if the event source should be polled in runEventSources() or not. 97*fdd8201dSApple OSS Distributions * @param inEventSource The event source to check. 98*fdd8201dSApple OSS Distributions */ 99*fdd8201dSApple OSS Distributions bool eventSourcePerformsWork(IOEventSource *inEventSource); 100*fdd8201dSApple OSS Distributions 101*fdd8201dSApple OSS Distributions /*! @function releaseEventChain 102*fdd8201dSApple OSS Distributions * @abstract Static function that releases the events in a chain and sets 103*fdd8201dSApple OSS Distributions * their work loops to NULL. 104*fdd8201dSApple OSS Distributions */ 105*fdd8201dSApple OSS Distributions static void releaseEventChain(LIBKERN_CONSUMED IOEventSource *eventChain); 106*fdd8201dSApple OSS Distributions 107*fdd8201dSApple OSS Distributions protected: 108*fdd8201dSApple OSS Distributions 109*fdd8201dSApple OSS Distributions /*! @typedef maintCommandEnum 110*fdd8201dSApple OSS Distributions * @discussion Enumeration of commands that _maintCommand can deal with. 111*fdd8201dSApple OSS Distributions * @constant mAddEvent Used to tag a Remove event source command. 112*fdd8201dSApple OSS Distributions * @constant mRemoveEvent Used to tag a Remove event source command. 113*fdd8201dSApple OSS Distributions */ 114*fdd8201dSApple OSS Distributions typedef enum { mAddEvent, mRemoveEvent } maintCommandEnum; 115*fdd8201dSApple OSS Distributions 116*fdd8201dSApple OSS Distributions /*! @var gateLock 117*fdd8201dSApple OSS Distributions * Mutual exclusion lock that is used by close and open Gate functions. 118*fdd8201dSApple OSS Distributions * This is a recursive lock, which allows multiple layers of code to share a single IOWorkLoop without deadlock. This is common in IOKit since threads of execution tend to follow the service plane in the IORegistry, and multiple objects along the call path may acquire the gate for the same (shared) workloop. 119*fdd8201dSApple OSS Distributions */ 120*fdd8201dSApple OSS Distributions IORecursiveLock *gateLock; 121*fdd8201dSApple OSS Distributions 122*fdd8201dSApple OSS Distributions /*! @var eventChain 123*fdd8201dSApple OSS Distributions * Pointer to first event source in linked list. 124*fdd8201dSApple OSS Distributions */ 125*fdd8201dSApple OSS Distributions IOEventSource *eventChain; 126*fdd8201dSApple OSS Distributions 127*fdd8201dSApple OSS Distributions /*! @var controlG 128*fdd8201dSApple OSS Distributions * Internal control gate to maintain event system. 129*fdd8201dSApple OSS Distributions */ 130*fdd8201dSApple OSS Distributions IOCommandGate *controlG; 131*fdd8201dSApple OSS Distributions 132*fdd8201dSApple OSS Distributions /*! @var workToDoLock 133*fdd8201dSApple OSS Distributions * The spin lock that is used to guard the 'workToDo' variable. 134*fdd8201dSApple OSS Distributions */ 135*fdd8201dSApple OSS Distributions IOSimpleLock *workToDoLock; 136*fdd8201dSApple OSS Distributions 137*fdd8201dSApple OSS Distributions /*! @var workThread 138*fdd8201dSApple OSS Distributions * Work loop thread. 139*fdd8201dSApple OSS Distributions */ 140*fdd8201dSApple OSS Distributions IOThread workThread; 141*fdd8201dSApple OSS Distributions 142*fdd8201dSApple OSS Distributions /*! @var workToDo 143*fdd8201dSApple OSS Distributions * Used to to indicate that an interrupt has fired and needs to be processed. 144*fdd8201dSApple OSS Distributions */ 145*fdd8201dSApple OSS Distributions volatile bool workToDo; 146*fdd8201dSApple OSS Distributions 147*fdd8201dSApple OSS Distributions /*! @var loopRestart 148*fdd8201dSApple OSS Distributions * Set if an event chain has been changed and the system has to be rechecked from start. (Internal use only) 149*fdd8201dSApple OSS Distributions */ 150*fdd8201dSApple OSS Distributions bool loopRestart; 151*fdd8201dSApple OSS Distributions 152*fdd8201dSApple OSS Distributions /*! @struct ExpansionData 153*fdd8201dSApple OSS Distributions * @discussion This structure will be used to expand the capablilties of the IOWorkLoop in the future. 154*fdd8201dSApple OSS Distributions */ 155*fdd8201dSApple OSS Distributions struct ExpansionData { 156*fdd8201dSApple OSS Distributions IOOptionBits options; 157*fdd8201dSApple OSS Distributions IOEventSource *passiveEventChain; 158*fdd8201dSApple OSS Distributions #if IOKITSTATS 159*fdd8201dSApple OSS Distributions struct IOWorkLoopCounter *counter; 160*fdd8201dSApple OSS Distributions #else 161*fdd8201dSApple OSS Distributions void *iokitstatsReserved; 162*fdd8201dSApple OSS Distributions #endif 163*fdd8201dSApple OSS Distributions uint64_t lockInterval; 164*fdd8201dSApple OSS Distributions uint64_t lockTime; 165*fdd8201dSApple OSS Distributions }; 166*fdd8201dSApple OSS Distributions 167*fdd8201dSApple OSS Distributions /*! @var reserved 168*fdd8201dSApple OSS Distributions * Reserved for future use. (Internal use only) 169*fdd8201dSApple OSS Distributions */ 170*fdd8201dSApple OSS Distributions ExpansionData *reserved; 171*fdd8201dSApple OSS Distributions 172*fdd8201dSApple OSS Distributions /*! @function _maintRequest 173*fdd8201dSApple OSS Distributions * @abstract Synchronous implementation of addEventSource and removeEventSource functions. 174*fdd8201dSApple OSS Distributions * @discussion This function implements the commands as defined in the maintCommandEnum. It can be subclassed but it isn't an external API in the usual sense. A subclass implementation of _maintRequest would be called synchronously with respect to the work loop and it should be implemented in the usual way that an ioctl would be. 175*fdd8201dSApple OSS Distributions * @return kIOReturnUnsupported if the command given is not implemented, kIOReturnSuccess otherwise. 176*fdd8201dSApple OSS Distributions */ 177*fdd8201dSApple OSS Distributions virtual IOReturn _maintRequest(void *command, void *data, void *, void *); 178*fdd8201dSApple OSS Distributions 179*fdd8201dSApple OSS Distributions /*! @function free 180*fdd8201dSApple OSS Distributions * @discussion Mandatory free of the object independent of the current retain count. If the work loop is running, this method will not return until the thread has successfully terminated. Each event source in the chain will be released and the working semaphore will be destroyed. 181*fdd8201dSApple OSS Distributions * <br><br> 182*fdd8201dSApple OSS Distributions * If the client has some outstanding requests on an event they will never be informed of completion. If an external thread is blocked on any of the event sources they will be awakened with a KERN_INTERUPTED status. 183*fdd8201dSApple OSS Distributions */ 184*fdd8201dSApple OSS Distributions virtual void free() APPLE_KEXT_OVERRIDE; 185*fdd8201dSApple OSS Distributions 186*fdd8201dSApple OSS Distributions /*! @function threadMain 187*fdd8201dSApple OSS Distributions * @discussion Work loop threads main function. This function consists of 3 188*fdd8201dSApple OSS Distributions * loops: the outermost loop is the semaphore clear and wait loop, the middle 189*fdd8201dSApple OSS Distributions * loop terminates when there is no more work, and the inside loop walks the 190*fdd8201dSApple OSS Distributions * event list calling the checkForWork method in each event source. If an 191*fdd8201dSApple OSS Distributions * event source has more work to do, it can set the more flag and the middle 192*fdd8201dSApple OSS Distributions * loop will repeat. When no more work is outstanding the outermost will 193*fdd8201dSApple OSS Distributions * sleep until an event is signalled. 194*fdd8201dSApple OSS Distributions */ 195*fdd8201dSApple OSS Distributions virtual void threadMain(); 196*fdd8201dSApple OSS Distributions 197*fdd8201dSApple OSS Distributions public: 198*fdd8201dSApple OSS Distributions 199*fdd8201dSApple OSS Distributions /*! @function workLoop 200*fdd8201dSApple OSS Distributions * @abstract Factory member function to construct and intialize a work loop. 201*fdd8201dSApple OSS Distributions * @result Returns a workLoop instance if constructed successfully, 0 otherwise. 202*fdd8201dSApple OSS Distributions */ 203*fdd8201dSApple OSS Distributions static OSPtr<IOWorkLoop> workLoop(); 204*fdd8201dSApple OSS Distributions 205*fdd8201dSApple OSS Distributions /*! @function workLoopWithOptions(IOOptionBits options) 206*fdd8201dSApple OSS Distributions * @abstract Factory member function to constuct and intialize a work loop. 207*fdd8201dSApple OSS Distributions * @param options Options - kPreciousStack to avoid stack deallocation on paging path. 208*fdd8201dSApple OSS Distributions * @result Returns a workLoop instance if constructed successfully, 0 otherwise. 209*fdd8201dSApple OSS Distributions */ 210*fdd8201dSApple OSS Distributions static OSPtr<IOWorkLoop> workLoopWithOptions(IOOptionBits options); 211*fdd8201dSApple OSS Distributions 212*fdd8201dSApple OSS Distributions /*! @function init 213*fdd8201dSApple OSS Distributions * @discussion Initializes an instance of the workloop. This method creates and initializes the signaling semaphore, the controller gate lock, and spawns the thread that will continue executing. 214*fdd8201dSApple OSS Distributions * @result Returns true if initialized successfully, false otherwise. 215*fdd8201dSApple OSS Distributions */ 216*fdd8201dSApple OSS Distributions virtual bool init() APPLE_KEXT_OVERRIDE; 217*fdd8201dSApple OSS Distributions 218*fdd8201dSApple OSS Distributions /*! @function getThread 219*fdd8201dSApple OSS Distributions * @abstract Gets the workThread. 220*fdd8201dSApple OSS Distributions * @result Returns workThread. 221*fdd8201dSApple OSS Distributions */ 222*fdd8201dSApple OSS Distributions virtual IOThread getThread() const; 223*fdd8201dSApple OSS Distributions 224*fdd8201dSApple OSS Distributions /*! @function onThread 225*fdd8201dSApple OSS Distributions * @abstract Is the current execution context on the work thread? 226*fdd8201dSApple OSS Distributions * @result Returns true if IOThreadSelf() == workThread. 227*fdd8201dSApple OSS Distributions */ 228*fdd8201dSApple OSS Distributions virtual bool onThread() const; 229*fdd8201dSApple OSS Distributions 230*fdd8201dSApple OSS Distributions /*! @function inGate 231*fdd8201dSApple OSS Distributions * @abstract Is the current execution context holding the work-loop's gate? 232*fdd8201dSApple OSS Distributions * @result Returns true if IOThreadSelf() is gate holder. 233*fdd8201dSApple OSS Distributions */ 234*fdd8201dSApple OSS Distributions virtual bool inGate() const; 235*fdd8201dSApple OSS Distributions 236*fdd8201dSApple OSS Distributions /*! @function addEventSource 237*fdd8201dSApple OSS Distributions * @discussion Add an event source to be monitored by the work loop. This function does not return until the work loop has acknowledged the arrival of the new event source. When a new event has been added the threadMain will always restart its loop and check all outstanding events. The event source is retained by the work loop. 238*fdd8201dSApple OSS Distributions * @param newEvent Pointer to IOEventSource subclass to add. 239*fdd8201dSApple OSS Distributions * @result Always returns kIOReturnSuccess. 240*fdd8201dSApple OSS Distributions */ 241*fdd8201dSApple OSS Distributions virtual IOReturn addEventSource(IOEventSource *newEvent); 242*fdd8201dSApple OSS Distributions 243*fdd8201dSApple OSS Distributions /*! @function removeEventSource 244*fdd8201dSApple OSS Distributions * @discussion Remove an event source from the work loop. This function does not return until the work loop has acknowledged the removal of the event source. When an event has been removed the threadMain will always restart its loop and check all outstanding events. The event source will be released before return. 245*fdd8201dSApple OSS Distributions * @param toRemove Pointer to IOEventSource subclass to remove. 246*fdd8201dSApple OSS Distributions * @result Returns kIOReturnSuccess if successful, kIOReturnBadArgument if toRemove couldn't be found. 247*fdd8201dSApple OSS Distributions */ 248*fdd8201dSApple OSS Distributions virtual IOReturn removeEventSource(IOEventSource *toRemove); 249*fdd8201dSApple OSS Distributions 250*fdd8201dSApple OSS Distributions /*! @function enableAllEventSources 251*fdd8201dSApple OSS Distributions * @abstract Calls enable() in all event sources. 252*fdd8201dSApple OSS Distributions * @discussion For all event sources in eventChain, call enable() function. See IOEventSource::enable(). 253*fdd8201dSApple OSS Distributions */ 254*fdd8201dSApple OSS Distributions virtual void enableAllEventSources() const; 255*fdd8201dSApple OSS Distributions 256*fdd8201dSApple OSS Distributions /*! @function disableAllEventSources 257*fdd8201dSApple OSS Distributions * @abstract Calls disable() in all event sources. 258*fdd8201dSApple OSS Distributions * @discussion For all event sources in eventChain, call disable() function. See IOEventSource::disable(). 259*fdd8201dSApple OSS Distributions */ 260*fdd8201dSApple OSS Distributions virtual void disableAllEventSources() const; 261*fdd8201dSApple OSS Distributions 262*fdd8201dSApple OSS Distributions /*! @function enableAllInterrupts 263*fdd8201dSApple OSS Distributions * @abstract Calls enable() in all interrupt event sources. 264*fdd8201dSApple OSS Distributions * @discussion For all event sources (ES) for which OSDynamicCast(IOInterruptEventSource, ES) is valid, in eventChain call enable() function. See IOEventSource::enable(). 265*fdd8201dSApple OSS Distributions */ 266*fdd8201dSApple OSS Distributions virtual void enableAllInterrupts() const; 267*fdd8201dSApple OSS Distributions 268*fdd8201dSApple OSS Distributions /*! @function disableAllInterrupts 269*fdd8201dSApple OSS Distributions * @abstract Calls disable() in all interrupt event sources. 270*fdd8201dSApple OSS Distributions * @discussion For all event sources (ES) for which OSDynamicCast(IOInterruptEventSource, ES) is valid, in eventChain call disable() function. See IOEventSource::disable(). 271*fdd8201dSApple OSS Distributions */ 272*fdd8201dSApple OSS Distributions virtual void disableAllInterrupts() const; 273*fdd8201dSApple OSS Distributions 274*fdd8201dSApple OSS Distributions 275*fdd8201dSApple OSS Distributions protected: 276*fdd8201dSApple OSS Distributions // Internal APIs used by event sources to control the thread 277*fdd8201dSApple OSS Distributions friend class IOEventSource; 278*fdd8201dSApple OSS Distributions friend class IOTimerEventSource; 279*fdd8201dSApple OSS Distributions friend class IOCommandGate; 280*fdd8201dSApple OSS Distributions #if IOKITSTATS 281*fdd8201dSApple OSS Distributions friend class IOStatistics; 282*fdd8201dSApple OSS Distributions #endif 283*fdd8201dSApple OSS Distributions virtual void signalWorkAvailable(); 284*fdd8201dSApple OSS Distributions virtual void openGate(); 285*fdd8201dSApple OSS Distributions virtual void closeGate(); 286*fdd8201dSApple OSS Distributions virtual bool tryCloseGate(); 287*fdd8201dSApple OSS Distributions virtual int sleepGate(void *event, UInt32 interuptibleType); 288*fdd8201dSApple OSS Distributions virtual void wakeupGate(void *event, bool oneThread); 289*fdd8201dSApple OSS Distributions 290*fdd8201dSApple OSS Distributions public: 291*fdd8201dSApple OSS Distributions /* methods available in Mac OS X 10.1 or later */ 292*fdd8201dSApple OSS Distributions 293*fdd8201dSApple OSS Distributions /*! @function runAction 294*fdd8201dSApple OSS Distributions * @abstract Single thread a call to an action with the work-loop. 295*fdd8201dSApple OSS Distributions * @discussion Client function that causes the given action to be called in a single threaded manner. Beware: the work-loop's gate is recursive and runAction can cause direct or indirect re-entrancy. When executing on a client's thread, runAction will sleep until the work-loop's gate opens for execution of client actions, the action is single threaded against all other work-loop event sources. 296*fdd8201dSApple OSS Distributions * @param action Pointer to function to be executed in work-loop context. 297*fdd8201dSApple OSS Distributions * @param arg0 Parameter for action parameter, defaults to 0. 298*fdd8201dSApple OSS Distributions * @param arg1 Parameter for action parameter, defaults to 0. 299*fdd8201dSApple OSS Distributions * @param arg2 Parameter for action parameter, defaults to 0. 300*fdd8201dSApple OSS Distributions * @param arg3 Parameter for action parameter, defaults to 0. 301*fdd8201dSApple OSS Distributions * @result Returns the value of the Action callout. 302*fdd8201dSApple OSS Distributions */ 303*fdd8201dSApple OSS Distributions virtual IOReturn runAction(Action action, OSObject *target, 304*fdd8201dSApple OSS Distributions void *arg0 = NULL, void *arg1 = NULL, 305*fdd8201dSApple OSS Distributions void *arg2 = NULL, void *arg3 = NULL); 306*fdd8201dSApple OSS Distributions 307*fdd8201dSApple OSS Distributions #ifdef __BLOCKS__ 308*fdd8201dSApple OSS Distributions /*! @function runAction 309*fdd8201dSApple OSS Distributions * @abstract Single thread a call to an action with the work-loop. 310*fdd8201dSApple OSS Distributions * @discussion Client function that causes the given action to be called in a single threaded manner. Beware: the work-loop's gate is recursive and runAction can cause direct or indirect re-entrancy. When executing on a client's thread, runAction will sleep until the work-loop's gate opens for execution of client actions, the action is single threaded against all other work-loop event sources. 311*fdd8201dSApple OSS Distributions * @param action Block to be executed in work-loop context. 312*fdd8201dSApple OSS Distributions * @result Returns the result of the action block. 313*fdd8201dSApple OSS Distributions */ 314*fdd8201dSApple OSS Distributions IOReturn runActionBlock(ActionBlock action); 315*fdd8201dSApple OSS Distributions #endif /* __BLOCKS__ */ 316*fdd8201dSApple OSS Distributions 317*fdd8201dSApple OSS Distributions /*! @function runEventSources 318*fdd8201dSApple OSS Distributions * @discussion Consists of the inner 2 loops of the threadMain function(qv). 319*fdd8201dSApple OSS Distributions * The outer loop terminates when there is no more work, and the inside loop 320*fdd8201dSApple OSS Distributions * walks the event list calling the checkForWork method in each event source. 321*fdd8201dSApple OSS Distributions * If an event source has more work to do, it can set the more flag and the 322*fdd8201dSApple OSS Distributions * outer loop will repeat. 323*fdd8201dSApple OSS Distributions * <br><br> 324*fdd8201dSApple OSS Distributions * This function can be used to clear a priority inversion between the normal 325*fdd8201dSApple OSS Distributions * workloop thread and multimedia's real time threads. The problem is that 326*fdd8201dSApple OSS Distributions * the interrupt action routine is often held off by high priority threads. 327*fdd8201dSApple OSS Distributions * So if they want to get their data now they will have to call us and ask if 328*fdd8201dSApple OSS Distributions * any data is available. The multi-media user client will arrange for this 329*fdd8201dSApple OSS Distributions * function to be called, which causes any pending interrupts to be processed 330*fdd8201dSApple OSS Distributions * and the completion routines called. By the time the function returns all 331*fdd8201dSApple OSS Distributions * outstanding work will have been completed at the real time threads 332*fdd8201dSApple OSS Distributions * priority. 333*fdd8201dSApple OSS Distributions * 334*fdd8201dSApple OSS Distributions * @result Return false if the work loop is shutting down, true otherwise. 335*fdd8201dSApple OSS Distributions */ 336*fdd8201dSApple OSS Distributions virtual bool runEventSources(); 337*fdd8201dSApple OSS Distributions 338*fdd8201dSApple OSS Distributions /*! @function setMaximumLockTime 339*fdd8201dSApple OSS Distributions * @discussion For diagnostics use in DEVELOPMENT kernels, set a time interval which if the work loop lock is held for this time or greater, IOWorkLoop will panic or log a backtrace. 340*fdd8201dSApple OSS Distributions * @param interval An absolute time interval, eg. created with clock_interval_to_absolutetime_interval(). 341*fdd8201dSApple OSS Distributions * @param options Pass IOWorkLoop::kTimeLockPanics to panic when the time is exceeded, otherwise a log will be generated with OSReportWithBacktrace(). 342*fdd8201dSApple OSS Distributions */ 343*fdd8201dSApple OSS Distributions void setMaximumLockTime(uint64_t interval, uint32_t options); 344*fdd8201dSApple OSS Distributions 345*fdd8201dSApple OSS Distributions protected: 346*fdd8201dSApple OSS Distributions // Internal APIs used by event sources to control the thread 347*fdd8201dSApple OSS Distributions virtual int sleepGate(void *event, AbsoluteTime deadline, UInt32 interuptibleType); 348*fdd8201dSApple OSS Distributions 349*fdd8201dSApple OSS Distributions #if XNU_KERNEL_PRIVATE 350*fdd8201dSApple OSS Distributions void lockTime(void); 351*fdd8201dSApple OSS Distributions #endif /* XNU_KERNEL_PRIVATE */ 352*fdd8201dSApple OSS Distributions 353*fdd8201dSApple OSS Distributions protected: 354*fdd8201dSApple OSS Distributions #if __LP64__ 355*fdd8201dSApple OSS Distributions OSMetaClassDeclareReservedUnused(IOWorkLoop, 0); 356*fdd8201dSApple OSS Distributions OSMetaClassDeclareReservedUnused(IOWorkLoop, 1); 357*fdd8201dSApple OSS Distributions OSMetaClassDeclareReservedUnused(IOWorkLoop, 2); 358*fdd8201dSApple OSS Distributions #else 359*fdd8201dSApple OSS Distributions OSMetaClassDeclareReservedUsedX86(IOWorkLoop, 0); 360*fdd8201dSApple OSS Distributions OSMetaClassDeclareReservedUsedX86(IOWorkLoop, 1); 361*fdd8201dSApple OSS Distributions OSMetaClassDeclareReservedUsedX86(IOWorkLoop, 2); 362*fdd8201dSApple OSS Distributions #endif 363*fdd8201dSApple OSS Distributions OSMetaClassDeclareReservedUnused(IOWorkLoop, 3); 364*fdd8201dSApple OSS Distributions OSMetaClassDeclareReservedUnused(IOWorkLoop, 4); 365*fdd8201dSApple OSS Distributions OSMetaClassDeclareReservedUnused(IOWorkLoop, 5); 366*fdd8201dSApple OSS Distributions OSMetaClassDeclareReservedUnused(IOWorkLoop, 6); 367*fdd8201dSApple OSS Distributions OSMetaClassDeclareReservedUnused(IOWorkLoop, 7); 368*fdd8201dSApple OSS Distributions }; 369*fdd8201dSApple OSS Distributions 370*fdd8201dSApple OSS Distributions #endif /* !__IOKIT_IOWORKLOOP_H */ 371