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/IOConditionLock.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 /* Copyright (c) 1997 Apple Computer, Inc.  All rights reserved.
   29  * Copyright (c) 1994-1996 NeXT Software, Inc.  All rights reserved. 
   30  *
   31  * AppleIOPSSafeCondLock.m. Lock object with exported condition variable, 
   32  *      kernel version.
   33  *
   34  * HISTORY
   35  * 1997-11-
   36  * 01-Aug-91    Doug Mitchell at NeXT
   37  *      Created. 
   38  */
   39 
   40 #include <IOKit/IOConditionLock.h>
   41 
   42 #define super OSObject
   43 OSDefineMetaClassAndStructors(IOConditionLock, OSObject)
   44 
   45 bool IOConditionLock::initWithCondition(int inCondition, bool inIntr)
   46 {
   47     if (!super::init())
   48         return false;
   49 
   50     cond_interlock = IOLockAlloc();
   51     sleep_interlock = IOLockAlloc();
   52 
   53     condition = inCondition;
   54     want_lock    = false;
   55     waiting      = false;
   56     interruptible = (inIntr) ? THREAD_INTERRUPTIBLE : THREAD_UNINT;
   57 
   58     return cond_interlock && sleep_interlock;
   59 }
   60 
   61 IOConditionLock *IOConditionLock::withCondition(int condition, bool intr)
   62 {
   63     IOConditionLock *me = new IOConditionLock;
   64 
   65     if (me && !me->initWithCondition(condition, intr)) {
   66         me->release();
   67         return 0;
   68     }
   69 
   70     return me;
   71 }
   72 void IOConditionLock::free()
   73 {
   74     if (cond_interlock)
   75         IOLockFree(cond_interlock);
   76     if (sleep_interlock)
   77         IOLockFree(sleep_interlock);
   78     super::free();
   79 }
   80 
   81 bool IOConditionLock::getInterruptible() const
   82 {
   83     return interruptible;
   84 }
   85 
   86 int IOConditionLock:: getCondition() const
   87 {
   88     return condition;
   89 }
   90 
   91 int IOConditionLock:: setCondition(int inCondition)
   92 {
   93     int old = condition;
   94 
   95     condition = inCondition;
   96     thread_wakeup_one((void *) &condition);
   97 
   98     return old;
   99 }
  100 
  101 void IOConditionLock::unlock()
  102 {
  103     IOTakeLock(sleep_interlock);
  104 
  105     thread_wakeup_one((void *) &condition);
  106 
  107     want_lock = false;
  108     if (waiting) {
  109         waiting = false;
  110         IOLockWakeup(sleep_interlock, this, /* one-thread */ false);    // Wakeup everybody
  111     }
  112 
  113     IOUnlock(sleep_interlock);
  114 }
  115 
  116 void IOConditionLock::unlockWith(int inCondition)
  117 {
  118     IOTakeLock(sleep_interlock);
  119     IOTakeLock(cond_interlock);
  120     
  121     condition = inCondition;
  122 
  123     IOUnlock(cond_interlock);
  124     IOUnlock(sleep_interlock);
  125 
  126     unlock();
  127 }
  128 
  129 bool IOConditionLock::tryLock()
  130 {
  131     bool result;
  132 
  133     IOTakeLock(sleep_interlock);
  134 
  135     result = !want_lock;
  136     if (result)
  137         want_lock = true;
  138 
  139     IOUnlock(sleep_interlock);
  140 
  141     return result;
  142 }
  143 
  144 int IOConditionLock::lock()
  145 {
  146     int thread_res = THREAD_AWAKENED;
  147 
  148     IOTakeLock(sleep_interlock);
  149     
  150     /* Try to acquire the want_lock bit. */
  151     while (want_lock && thread_res == THREAD_AWAKENED)
  152     {
  153         waiting = true;
  154         thread_res = IOLockSleep(sleep_interlock, (void *) this, interruptible);
  155     }
  156     if (thread_res == THREAD_AWAKENED)
  157         want_lock = true;
  158     
  159     IOUnlock(sleep_interlock);
  160 
  161     return thread_res;
  162 }
  163 
  164 int IOConditionLock::lockWhen(int inCondition)
  165 {
  166     int thread_res;
  167     
  168     do
  169     {
  170         /* First get the actual lock */
  171         thread_res = lock();
  172         if (thread_res != THREAD_AWAKENED)
  173             break;      // Failed to acquire lock
  174 
  175         if (inCondition == condition)
  176             break;      // Hold lock and condition is expected value
  177 
  178         /*
  179          * Need to hold a IOTakeLock when we call thread_sleep().
  180          * Both _cond_interlock and want_lock must be held to 
  181          * change _condition.
  182          */
  183         IOTakeLock(cond_interlock);
  184         unlock();       // Release lock and sleep
  185         
  186         /*
  187          * this is the critical section on a multi in which
  188          * another thread could hold _sleep_interlock, but they 
  189          * can't change _condition. Holding _cond_interlock here
  190          * (until after assert_wait() is called from 
  191          * thread_sleep()) ensures that we'll be notified
  192          * of changes in _condition.
  193          */
  194         assert_wait((void *) &condition, interruptible); /* assert event */
  195         IOUnlock(cond_interlock);                        /* release the lock */
  196         thread_res = thread_block(THREAD_CONTINUE_NULL); /* block ourselves */
  197     } while (thread_res == THREAD_AWAKENED);
  198     
  199     return thread_res;
  200 }

Cache object: b4f5cbcf55aedfb71a937b3a90761e66


[ 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.