utlock.c revision 298714
1255570Strasz/****************************************************************************** 2255570Strasz * 3255570Strasz * Module Name: utlock - Reader/Writer lock interfaces 4255570Strasz * 5255570Strasz *****************************************************************************/ 6255570Strasz 7255570Strasz/* 8255570Strasz * Copyright (C) 2000 - 2016, Intel Corp. 9255570Strasz * All rights reserved. 10255570Strasz * 11255570Strasz * Redistribution and use in source and binary forms, with or without 12255570Strasz * modification, are permitted provided that the following conditions 13255570Strasz * are met: 14255570Strasz * 1. Redistributions of source code must retain the above copyright 15255570Strasz * notice, this list of conditions, and the following disclaimer, 16255570Strasz * without modification. 17255570Strasz * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18255570Strasz * substantially similar to the "NO WARRANTY" disclaimer below 19255570Strasz * ("Disclaimer") and any redistribution must be conditioned upon 20255570Strasz * including a substantially similar Disclaimer requirement for further 21255570Strasz * binary redistribution. 22255570Strasz * 3. Neither the names of the above-listed copyright holders nor the names 23255570Strasz * of any contributors may be used to endorse or promote products derived 24255570Strasz * from this software without specific prior written permission. 25255570Strasz * 26255570Strasz * Alternatively, this software may be distributed under the terms of the 27255570Strasz * GNU General Public License ("GPL") version 2 as published by the Free 28255570Strasz * Software Foundation. 29255570Strasz * 30255570Strasz * NO WARRANTY 31255570Strasz * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32255570Strasz * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33255570Strasz * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34255570Strasz * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35255570Strasz * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36255570Strasz * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37255570Strasz * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38255570Strasz * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39255570Strasz * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40255570Strasz * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41255570Strasz * POSSIBILITY OF SUCH DAMAGES. 42255570Strasz */ 43255570Strasz 44255570Strasz#include <contrib/dev/acpica/include/acpi.h> 45255570Strasz#include <contrib/dev/acpica/include/accommon.h> 46255570Strasz 47255570Strasz 48255570Strasz#define _COMPONENT ACPI_UTILITIES 49255570Strasz ACPI_MODULE_NAME ("utlock") 50255570Strasz 51255570Strasz 52255570Strasz/******************************************************************************* 53255570Strasz * 54255570Strasz * FUNCTION: AcpiUtCreateRwLock 55255570Strasz * AcpiUtDeleteRwLock 56255570Strasz * 57255570Strasz * PARAMETERS: Lock - Pointer to a valid RW lock 58255570Strasz * 59255570Strasz * RETURN: Status 60255570Strasz * 61255570Strasz * DESCRIPTION: Reader/writer lock creation and deletion interfaces. 62255570Strasz * 63255570Strasz ******************************************************************************/ 64255570Strasz 65255570StraszACPI_STATUS 66255570StraszAcpiUtCreateRwLock ( 67255570Strasz ACPI_RW_LOCK *Lock) 68265507Strasz{ 69265507Strasz ACPI_STATUS Status; 70255570Strasz 71255570Strasz 72255570Strasz Lock->NumReaders = 0; 73255570Strasz Status = AcpiOsCreateMutex (&Lock->ReaderMutex); 74265507Strasz if (ACPI_FAILURE (Status)) 75255570Strasz { 76255570Strasz return (Status); 77255570Strasz } 78255570Strasz 79255570Strasz Status = AcpiOsCreateMutex (&Lock->WriterMutex); 80255570Strasz return (Status); 81255570Strasz} 82255570Strasz 83255570Strasz 84255665Straszvoid 85255570StraszAcpiUtDeleteRwLock ( 86255570Strasz ACPI_RW_LOCK *Lock) 87255570Strasz{ 88255570Strasz 89255570Strasz AcpiOsDeleteMutex (Lock->ReaderMutex); 90255570Strasz AcpiOsDeleteMutex (Lock->WriterMutex); 91255570Strasz 92255570Strasz Lock->NumReaders = 0; 93255570Strasz Lock->ReaderMutex = NULL; 94255570Strasz Lock->WriterMutex = NULL; 95255570Strasz} 96255570Strasz 97255570Strasz 98255570Strasz/******************************************************************************* 99255570Strasz * 100255570Strasz * FUNCTION: AcpiUtAcquireReadLock 101255570Strasz * AcpiUtReleaseReadLock 102255570Strasz * 103255570Strasz * PARAMETERS: Lock - Pointer to a valid RW lock 104255570Strasz * 105255570Strasz * RETURN: Status 106255570Strasz * 107255570Strasz * DESCRIPTION: Reader interfaces for reader/writer locks. On acquisition, 108255570Strasz * only the first reader acquires the write mutex. On release, 109255570Strasz * only the last reader releases the write mutex. Although this 110255570Strasz * algorithm can in theory starve writers, this should not be a 111255570Strasz * problem with ACPICA since the subsystem is infrequently used 112255570Strasz * in comparison to (for example) an I/O system. 113255570Strasz * 114255570Strasz ******************************************************************************/ 115255570Strasz 116255570StraszACPI_STATUS 117255570StraszAcpiUtAcquireReadLock ( 118255570Strasz ACPI_RW_LOCK *Lock) 119255570Strasz{ 120255570Strasz ACPI_STATUS Status; 121255570Strasz 122255570Strasz 123255570Strasz Status = AcpiOsAcquireMutex (Lock->ReaderMutex, ACPI_WAIT_FOREVER); 124255570Strasz if (ACPI_FAILURE (Status)) 125255570Strasz { 126255570Strasz return (Status); 127255570Strasz } 128255570Strasz 129255570Strasz /* Acquire the write lock only for the first reader */ 130255570Strasz 131255570Strasz Lock->NumReaders++; 132255570Strasz if (Lock->NumReaders == 1) 133255570Strasz { 134255570Strasz Status = AcpiOsAcquireMutex (Lock->WriterMutex, ACPI_WAIT_FOREVER); 135255570Strasz } 136255570Strasz 137255570Strasz AcpiOsReleaseMutex (Lock->ReaderMutex); 138255570Strasz return (Status); 139255570Strasz} 140256189Strasz 141255570Strasz 142255570StraszACPI_STATUS 143255570StraszAcpiUtReleaseReadLock ( 144255570Strasz ACPI_RW_LOCK *Lock) 145255570Strasz{ 146255570Strasz ACPI_STATUS Status; 147255570Strasz 148255570Strasz 149255570Strasz Status = AcpiOsAcquireMutex (Lock->ReaderMutex, ACPI_WAIT_FOREVER); 150255570Strasz if (ACPI_FAILURE (Status)) 151255570Strasz { 152255570Strasz return (Status); 153255570Strasz } 154255570Strasz 155255570Strasz /* Release the write lock only for the very last reader */ 156255570Strasz 157255570Strasz Lock->NumReaders--; 158255570Strasz if (Lock->NumReaders == 0) 159255570Strasz { 160255570Strasz AcpiOsReleaseMutex (Lock->WriterMutex); 161255570Strasz } 162255570Strasz 163255570Strasz AcpiOsReleaseMutex (Lock->ReaderMutex); 164255570Strasz return (Status); 165255570Strasz} 166255570Strasz 167255570Strasz 168255570Strasz/******************************************************************************* 169255570Strasz * 170255570Strasz * FUNCTION: AcpiUtAcquireWriteLock 171255570Strasz * AcpiUtReleaseWriteLock 172255570Strasz * 173255570Strasz * PARAMETERS: Lock - Pointer to a valid RW lock 174255570Strasz * 175255570Strasz * RETURN: Status 176255570Strasz * 177255570Strasz * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or 178255570Strasz * release the writer mutex associated with the lock. Acquisition 179255570Strasz * of the lock is fully exclusive and will block all readers and 180255570Strasz * writers until it is released. 181255570Strasz * 182255570Strasz ******************************************************************************/ 183255570Strasz 184255570StraszACPI_STATUS 185255570StraszAcpiUtAcquireWriteLock ( 186255570Strasz ACPI_RW_LOCK *Lock) 187255570Strasz{ 188255570Strasz ACPI_STATUS Status; 189255570Strasz 190255570Strasz 191255570Strasz Status = AcpiOsAcquireMutex (Lock->WriterMutex, ACPI_WAIT_FOREVER); 192255570Strasz return (Status); 193255570Strasz} 194255570Strasz 195255570Strasz 196255570Straszvoid 197255570StraszAcpiUtReleaseWriteLock ( 198255570Strasz ACPI_RW_LOCK *Lock) 199255570Strasz{ 200255570Strasz 201255570Strasz AcpiOsReleaseMutex (Lock->WriterMutex); 202255570Strasz} 203255570Strasz