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