1 /******************************************************************************
   2  *
   3  * Module Name: utlock - Reader/Writer lock interfaces
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 
  44 #define __UTLOCK_C__
  45 
  46 #include "acpi.h"
  47 #include "accommon.h"
  48 
  49 
  50 #define _COMPONENT          ACPI_UTILITIES
  51         ACPI_MODULE_NAME    ("utlock")
  52 
  53 
  54 /*******************************************************************************
  55  *
  56  * FUNCTION:    AcpiUtCreateRwLock
  57  *              AcpiUtDeleteRwLock
  58  *
  59  * PARAMETERS:  Lock                - Pointer to a valid RW lock
  60  *
  61  * RETURN:      Status
  62  *
  63  * DESCRIPTION: Reader/writer lock creation and deletion interfaces.
  64  *
  65  ******************************************************************************/
  66 
  67 ACPI_STATUS
  68 AcpiUtCreateRwLock (
  69     ACPI_RW_LOCK            *Lock)
  70 {
  71     ACPI_STATUS             Status;
  72 
  73 
  74     Lock->NumReaders = 0;
  75     Status = AcpiOsCreateMutex (&Lock->ReaderMutex);
  76     if (ACPI_FAILURE (Status))
  77     {
  78         return (Status);
  79     }
  80 
  81     Status = AcpiOsCreateMutex (&Lock->WriterMutex);
  82     return (Status);
  83 }
  84 
  85 
  86 void
  87 AcpiUtDeleteRwLock (
  88     ACPI_RW_LOCK            *Lock)
  89 {
  90 
  91     AcpiOsDeleteMutex (Lock->ReaderMutex);
  92     AcpiOsDeleteMutex (Lock->WriterMutex);
  93 
  94     Lock->NumReaders = 0;
  95     Lock->ReaderMutex = NULL;
  96     Lock->WriterMutex = NULL;
  97 }
  98 
  99 
 100 /*******************************************************************************
 101  *
 102  * FUNCTION:    AcpiUtAcquireReadLock
 103  *              AcpiUtReleaseReadLock
 104  *
 105  * PARAMETERS:  Lock                - Pointer to a valid RW lock
 106  *
 107  * RETURN:      Status
 108  *
 109  * DESCRIPTION: Reader interfaces for reader/writer locks. On acquisition,
 110  *              only the first reader acquires the write mutex. On release,
 111  *              only the last reader releases the write mutex. Although this
 112  *              algorithm can in theory starve writers, this should not be a
 113  *              problem with ACPICA since the subsystem is infrequently used
 114  *              in comparison to (for example) an I/O system.
 115  *
 116  ******************************************************************************/
 117 
 118 ACPI_STATUS
 119 AcpiUtAcquireReadLock (
 120     ACPI_RW_LOCK            *Lock)
 121 {
 122     ACPI_STATUS             Status;
 123 
 124 
 125     Status = AcpiOsAcquireMutex (Lock->ReaderMutex, ACPI_WAIT_FOREVER);
 126     if (ACPI_FAILURE (Status))
 127     {
 128         return (Status);
 129     }
 130 
 131     /* Acquire the write lock only for the first reader */
 132 
 133     Lock->NumReaders++;
 134     if (Lock->NumReaders == 1)
 135     {
 136         Status = AcpiOsAcquireMutex (Lock->WriterMutex, ACPI_WAIT_FOREVER);
 137     }
 138 
 139     AcpiOsReleaseMutex (Lock->ReaderMutex);
 140     return (Status);
 141 }
 142 
 143 
 144 ACPI_STATUS
 145 AcpiUtReleaseReadLock (
 146     ACPI_RW_LOCK            *Lock)
 147 {
 148     ACPI_STATUS             Status;
 149 
 150 
 151     Status = AcpiOsAcquireMutex (Lock->ReaderMutex, ACPI_WAIT_FOREVER);
 152     if (ACPI_FAILURE (Status))
 153     {
 154         return (Status);
 155     }
 156 
 157     /* Release the write lock only for the very last reader */
 158 
 159     Lock->NumReaders--;
 160     if (Lock->NumReaders == 0)
 161     {
 162         AcpiOsReleaseMutex (Lock->WriterMutex);
 163     }
 164 
 165     AcpiOsReleaseMutex (Lock->ReaderMutex);
 166     return (Status);
 167 }
 168 
 169 
 170 /*******************************************************************************
 171  *
 172  * FUNCTION:    AcpiUtAcquireWriteLock
 173  *              AcpiUtReleaseWriteLock
 174  *
 175  * PARAMETERS:  Lock                - Pointer to a valid RW lock
 176  *
 177  * RETURN:      Status
 178  *
 179  * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or
 180  *              release the writer mutex associated with the lock. Acquisition
 181  *              of the lock is fully exclusive and will block all readers and
 182  *              writers until it is released.
 183  *
 184  ******************************************************************************/
 185 
 186 ACPI_STATUS
 187 AcpiUtAcquireWriteLock (
 188     ACPI_RW_LOCK            *Lock)
 189 {
 190     ACPI_STATUS             Status;
 191 
 192 
 193     Status = AcpiOsAcquireMutex (Lock->WriterMutex, ACPI_WAIT_FOREVER);
 194     return (Status);
 195 }
 196 
 197 
 198 void
 199 AcpiUtReleaseWriteLock (
 200     ACPI_RW_LOCK            *Lock)
 201 {
 202 
 203     AcpiOsReleaseMutex (Lock->WriterMutex);
 204 }