linux/drivers/acpi/acpica/utlock.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Module Name: utlock - Reader/Writer lock interfaces
   4 *
   5 *****************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2015, 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#include <acpi/acpi.h>
  45#include "accommon.h"
  46
  47#define _COMPONENT          ACPI_UTILITIES
  48ACPI_MODULE_NAME("utlock")
  49
  50/*******************************************************************************
  51 *
  52 * FUNCTION:    acpi_ut_create_rw_lock
  53 *              acpi_ut_delete_rw_lock
  54 *
  55 * PARAMETERS:  lock                - Pointer to a valid RW lock
  56 *
  57 * RETURN:      Status
  58 *
  59 * DESCRIPTION: Reader/writer lock creation and deletion interfaces.
  60 *
  61 ******************************************************************************/
  62acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock)
  63{
  64        acpi_status status;
  65
  66        lock->num_readers = 0;
  67        status = acpi_os_create_mutex(&lock->reader_mutex);
  68        if (ACPI_FAILURE(status)) {
  69                return (status);
  70        }
  71
  72        status = acpi_os_create_mutex(&lock->writer_mutex);
  73        return (status);
  74}
  75
  76void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock)
  77{
  78
  79        acpi_os_delete_mutex(lock->reader_mutex);
  80        acpi_os_delete_mutex(lock->writer_mutex);
  81
  82        lock->num_readers = 0;
  83        lock->reader_mutex = NULL;
  84        lock->writer_mutex = NULL;
  85}
  86
  87/*******************************************************************************
  88 *
  89 * FUNCTION:    acpi_ut_acquire_read_lock
  90 *              acpi_ut_release_read_lock
  91 *
  92 * PARAMETERS:  lock                - Pointer to a valid RW lock
  93 *
  94 * RETURN:      Status
  95 *
  96 * DESCRIPTION: Reader interfaces for reader/writer locks. On acquisition,
  97 *              only the first reader acquires the write mutex. On release,
  98 *              only the last reader releases the write mutex. Although this
  99 *              algorithm can in theory starve writers, this should not be a
 100 *              problem with ACPICA since the subsystem is infrequently used
 101 *              in comparison to (for example) an I/O system.
 102 *
 103 ******************************************************************************/
 104
 105acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock)
 106{
 107        acpi_status status;
 108
 109        status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
 110        if (ACPI_FAILURE(status)) {
 111                return (status);
 112        }
 113
 114        /* Acquire the write lock only for the first reader */
 115
 116        lock->num_readers++;
 117        if (lock->num_readers == 1) {
 118                status =
 119                    acpi_os_acquire_mutex(lock->writer_mutex,
 120                                          ACPI_WAIT_FOREVER);
 121        }
 122
 123        acpi_os_release_mutex(lock->reader_mutex);
 124        return (status);
 125}
 126
 127acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock)
 128{
 129        acpi_status status;
 130
 131        status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
 132        if (ACPI_FAILURE(status)) {
 133                return (status);
 134        }
 135
 136        /* Release the write lock only for the very last reader */
 137
 138        lock->num_readers--;
 139        if (lock->num_readers == 0) {
 140                acpi_os_release_mutex(lock->writer_mutex);
 141        }
 142
 143        acpi_os_release_mutex(lock->reader_mutex);
 144        return (status);
 145}
 146
 147/*******************************************************************************
 148 *
 149 * FUNCTION:    acpi_ut_acquire_write_lock
 150 *              acpi_ut_release_write_lock
 151 *
 152 * PARAMETERS:  lock                - Pointer to a valid RW lock
 153 *
 154 * RETURN:      Status
 155 *
 156 * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or
 157 *              release the writer mutex associated with the lock. Acquisition
 158 *              of the lock is fully exclusive and will block all readers and
 159 *              writers until it is released.
 160 *
 161 ******************************************************************************/
 162
 163acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock)
 164{
 165        acpi_status status;
 166
 167        status = acpi_os_acquire_mutex(lock->writer_mutex, ACPI_WAIT_FOREVER);
 168        return (status);
 169}
 170
 171void acpi_ut_release_write_lock(struct acpi_rw_lock *lock)
 172{
 173
 174        acpi_os_release_mutex(lock->writer_mutex);
 175}
 176