The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/iokit/Kernel/IOCommandGate.cpp

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
    5  * 
    6  * This file contains Original Code and/or Modifications of Original Code
    7  * as defined in and that are subject to the Apple Public Source License
    8  * Version 2.0 (the 'License'). You may not use this file except in
    9  * compliance with the License. The rights granted to you under the License
   10  * may not be used to create, or enable the creation or redistribution of,
   11  * unlawful or unlicensed copies of an Apple operating system, or to
   12  * circumvent, violate, or enable the circumvention or violation of, any
   13  * terms of an Apple operating system software license agreement.
   14  * 
   15  * Please obtain a copy of the License at
   16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
   17  * 
   18  * The Original Code and all software distributed under the License are
   19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   23  * Please see the License for the specific language governing rights and
   24  * limitations under the License.
   25  * 
   26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
   27  */
   28 #include <libkern/OSDebug.h>
   29 
   30 #include <IOKit/IOCommandGate.h>
   31 #include <IOKit/IOWorkLoop.h>
   32 #include <IOKit/IOReturn.h>
   33 #include <IOKit/IOTimeStamp.h>
   34 
   35 #define super IOEventSource
   36 
   37 OSDefineMetaClassAndStructors(IOCommandGate, IOEventSource)
   38 OSMetaClassDefineReservedUnused(IOCommandGate, 0);
   39 OSMetaClassDefineReservedUnused(IOCommandGate, 1);
   40 OSMetaClassDefineReservedUnused(IOCommandGate, 2);
   41 OSMetaClassDefineReservedUnused(IOCommandGate, 3);
   42 OSMetaClassDefineReservedUnused(IOCommandGate, 4);
   43 OSMetaClassDefineReservedUnused(IOCommandGate, 5);
   44 OSMetaClassDefineReservedUnused(IOCommandGate, 6);
   45 OSMetaClassDefineReservedUnused(IOCommandGate, 7);
   46 
   47 bool IOCommandGate::checkForWork() { return false; }
   48 
   49 bool IOCommandGate::init(OSObject *inOwner, Action inAction)
   50 {
   51     return super::init(inOwner, (IOEventSource::Action) inAction);
   52 }
   53 
   54 IOCommandGate *
   55 IOCommandGate::commandGate(OSObject *inOwner, Action inAction)
   56 {
   57     IOCommandGate *me = new IOCommandGate;
   58 
   59     if (me && !me->init(inOwner, inAction)) {
   60         me->release();
   61         return 0;
   62     }
   63 
   64     return me;
   65 }
   66 
   67 /* virtual */ void IOCommandGate::disable()
   68 {
   69     if (workLoop && !workLoop->inGate())
   70         OSReportWithBacktrace("IOCommandGate::disable() called when not gated");
   71 
   72     super::disable();
   73 }
   74 
   75 /* virtual */ void IOCommandGate::enable()
   76 {
   77     if (workLoop) {
   78         closeGate();
   79         super::enable();
   80         wakeupGate(&enabled, /* oneThread */ false); // Unblock sleeping threads
   81         openGate();
   82     }
   83 }
   84 
   85 /* virtual */ void IOCommandGate::free()
   86 {
   87     setWorkLoop(0);
   88     super::free();
   89 }
   90 
   91 /* virtual */ void IOCommandGate::setWorkLoop(IOWorkLoop *inWorkLoop)
   92 {
   93     uintptr_t *sleepersP = (uintptr_t *) &reserved;
   94     if (!inWorkLoop && workLoop) {              // tearing down
   95         closeGate();
   96         *sleepersP |= 1;
   97         while (*sleepersP >> 1) {
   98             thread_wakeup_with_result(&enabled, THREAD_INTERRUPTED);
   99             sleepGate(sleepersP, THREAD_UNINT);
  100         }
  101         *sleepersP = 0;
  102         openGate();
  103     }
  104     else
  105 
  106     super::setWorkLoop(inWorkLoop);
  107 }
  108 
  109 IOReturn IOCommandGate::runCommand(void *arg0, void *arg1,
  110                                    void *arg2, void *arg3)
  111 {
  112     return runAction((Action) action, arg0, arg1, arg2, arg3);
  113 }
  114 
  115 IOReturn IOCommandGate::attemptCommand(void *arg0, void *arg1,
  116                                        void *arg2, void *arg3)
  117 {
  118     return attemptAction((Action) action, arg0, arg1, arg2, arg3);
  119 }
  120 
  121 IOReturn IOCommandGate::runAction(Action inAction,
  122                                   void *arg0, void *arg1,
  123                                   void *arg2, void *arg3)
  124 {
  125     if (!inAction)
  126         return kIOReturnBadArgument;
  127 
  128     IOTimeStampConstant(IODBG_CMDQ(IOCMDQ_ACTION),
  129                         (unsigned int) inAction, (unsigned int) owner);
  130 
  131     // closeGate is recursive needn't worry if we already hold the lock.
  132     closeGate();
  133 
  134     // If the command gate is disabled and we aren't on the workloop thread
  135     // itself then sleep until we get enabled.
  136     IOReturn res;
  137     if (!workLoop->onThread()) {
  138         while (!enabled) {
  139             uintptr_t *sleepersP = (uintptr_t *) &reserved;
  140 
  141             *sleepersP += 2;
  142             IOReturn res = sleepGate(&enabled, THREAD_ABORTSAFE);
  143             *sleepersP -= 2;
  144 
  145             bool wakeupTearDown = (*sleepersP & 1);
  146             if (res || wakeupTearDown) {
  147                 openGate();
  148 
  149                  if (wakeupTearDown)
  150                      commandWakeup(sleepersP);  // No further resources used
  151 
  152                 return kIOReturnAborted;
  153             }
  154         }
  155     }
  156 
  157     // Must be gated and on the work loop or enabled
  158     res = (*inAction)(owner, arg0, arg1, arg2, arg3);
  159     openGate();
  160 
  161     return res;
  162 }
  163 
  164 IOReturn IOCommandGate::attemptAction(Action inAction,
  165                                       void *arg0, void *arg1,
  166                                       void *arg2, void *arg3)
  167 {
  168     IOReturn res;
  169 
  170     if (!inAction)
  171         return kIOReturnBadArgument;
  172 
  173     // Try to close the gate if can't get return immediately.
  174     if (!tryCloseGate())
  175         return kIOReturnCannotLock;
  176 
  177     // If the command gate is disabled then sleep until we get a wakeup
  178     if (!workLoop->onThread() && !enabled)
  179         res = kIOReturnNotPermitted;
  180     else {
  181         IOTimeStampConstant(IODBG_CMDQ(IOCMDQ_ACTION),
  182                             (unsigned int) inAction, (unsigned int) owner);
  183 
  184         res = (*inAction)(owner, arg0, arg1, arg2, arg3);
  185     }
  186 
  187     openGate();
  188 
  189     return res;
  190 }
  191 
  192 IOReturn IOCommandGate::commandSleep(void *event, UInt32 interruptible)
  193 {
  194     if (!workLoop->inGate())
  195         return kIOReturnNotPermitted;
  196 
  197     return sleepGate(event, interruptible);
  198 }
  199 
  200 void IOCommandGate::commandWakeup(void *event, bool oneThread)
  201 {
  202     wakeupGate(event, oneThread);
  203 }

Cache object: 298a7e4d39cae013bc25c03214c8f58d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.