linux/drivers/acpi/acpica/utlock.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/******************************************************************************
   3 *
   4 * Module Name: utlock - Reader/Writer lock interfaces
   5 *
   6 * Copyright (C) 2000 - 2020, Intel Corp.
   7 *
   8 *****************************************************************************/
   9
  10#include <acpi/acpi.h>
  11#include "accommon.h"
  12
  13#define _COMPONENT          ACPI_UTILITIES
  14ACPI_MODULE_NAME("utlock")
  15
  16/*******************************************************************************
  17 *
  18 * FUNCTION:    acpi_ut_create_rw_lock
  19 *              acpi_ut_delete_rw_lock
  20 *
  21 * PARAMETERS:  lock                - Pointer to a valid RW lock
  22 *
  23 * RETURN:      Status
  24 *
  25 * DESCRIPTION: Reader/writer lock creation and deletion interfaces.
  26 *
  27 ******************************************************************************/
  28acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock)
  29{
  30        acpi_status status;
  31
  32        lock->num_readers = 0;
  33        status = acpi_os_create_mutex(&lock->reader_mutex);
  34        if (ACPI_FAILURE(status)) {
  35                return (status);
  36        }
  37
  38        status = acpi_os_create_mutex(&lock->writer_mutex);
  39        return (status);
  40}
  41
  42void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock)
  43{
  44
  45        acpi_os_delete_mutex(lock->reader_mutex);
  46        acpi_os_delete_mutex(lock->writer_mutex);
  47
  48        lock->num_readers = 0;
  49        lock->reader_mutex = NULL;
  50        lock->writer_mutex = NULL;
  51}
  52
  53/*******************************************************************************
  54 *
  55 * FUNCTION:    acpi_ut_acquire_read_lock
  56 *              acpi_ut_release_read_lock
  57 *
  58 * PARAMETERS:  lock                - Pointer to a valid RW lock
  59 *
  60 * RETURN:      Status
  61 *
  62 * DESCRIPTION: Reader interfaces for reader/writer locks. On acquisition,
  63 *              only the first reader acquires the write mutex. On release,
  64 *              only the last reader releases the write mutex. Although this
  65 *              algorithm can in theory starve writers, this should not be a
  66 *              problem with ACPICA since the subsystem is infrequently used
  67 *              in comparison to (for example) an I/O system.
  68 *
  69 ******************************************************************************/
  70
  71acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock)
  72{
  73        acpi_status status;
  74
  75        status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
  76        if (ACPI_FAILURE(status)) {
  77                return (status);
  78        }
  79
  80        /* Acquire the write lock only for the first reader */
  81
  82        lock->num_readers++;
  83        if (lock->num_readers == 1) {
  84                status =
  85                    acpi_os_acquire_mutex(lock->writer_mutex,
  86                                          ACPI_WAIT_FOREVER);
  87        }
  88
  89        acpi_os_release_mutex(lock->reader_mutex);
  90        return (status);
  91}
  92
  93acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock)
  94{
  95        acpi_status status;
  96
  97        status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
  98        if (ACPI_FAILURE(status)) {
  99                return (status);
 100        }
 101
 102        /* Release the write lock only for the very last reader */
 103
 104        lock->num_readers--;
 105        if (lock->num_readers == 0) {
 106                acpi_os_release_mutex(lock->writer_mutex);
 107        }
 108
 109        acpi_os_release_mutex(lock->reader_mutex);
 110        return (status);
 111}
 112
 113/*******************************************************************************
 114 *
 115 * FUNCTION:    acpi_ut_acquire_write_lock
 116 *              acpi_ut_release_write_lock
 117 *
 118 * PARAMETERS:  lock                - Pointer to a valid RW lock
 119 *
 120 * RETURN:      Status
 121 *
 122 * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or
 123 *              release the writer mutex associated with the lock. Acquisition
 124 *              of the lock is fully exclusive and will block all readers and
 125 *              writers until it is released.
 126 *
 127 ******************************************************************************/
 128
 129acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock)
 130{
 131        acpi_status status;
 132
 133        status = acpi_os_acquire_mutex(lock->writer_mutex, ACPI_WAIT_FOREVER);
 134        return (status);
 135}
 136
 137void acpi_ut_release_write_lock(struct acpi_rw_lock *lock)
 138{
 139
 140        acpi_os_release_mutex(lock->writer_mutex);
 141}
 142