Branch data Line data Source code
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 14 : : ACPI_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 : : ******************************************************************************/ 28 : 30 : acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock) 29 : : { 30 : 30 : acpi_status status; 31 : : 32 : 30 : lock->num_readers = 0; 33 : 30 : status = acpi_os_create_mutex(&lock->reader_mutex); 34 [ + - ]: 30 : if (ACPI_FAILURE(status)) { 35 : : return (status); 36 : : } 37 : : 38 : 30 : status = acpi_os_create_mutex(&lock->writer_mutex); 39 : 30 : return (status); 40 : : } 41 : : 42 : 0 : void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock) 43 : : { 44 : : 45 : 0 : acpi_os_delete_mutex(lock->reader_mutex); 46 : 0 : acpi_os_delete_mutex(lock->writer_mutex); 47 : : 48 : 0 : lock->num_readers = 0; 49 : 0 : lock->reader_mutex = NULL; 50 : 0 : lock->writer_mutex = NULL; 51 : 0 : } 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 : : 71 : 210 : acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock) 72 : : { 73 : 210 : acpi_status status; 74 : : 75 : 210 : status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER); 76 [ + - ]: 210 : if (ACPI_FAILURE(status)) { 77 : : return (status); 78 : : } 79 : : 80 : : /* Acquire the write lock only for the first reader */ 81 : : 82 : 210 : lock->num_readers++; 83 [ + - ]: 210 : if (lock->num_readers == 1) { 84 : 210 : status = 85 : 210 : acpi_os_acquire_mutex(lock->writer_mutex, 86 : : ACPI_WAIT_FOREVER); 87 : : } 88 : : 89 : 210 : acpi_os_release_mutex(lock->reader_mutex); 90 : 210 : return (status); 91 : : } 92 : : 93 : 210 : acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock) 94 : : { 95 : 210 : acpi_status status; 96 : : 97 : 210 : status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER); 98 [ + - ]: 210 : if (ACPI_FAILURE(status)) { 99 : : return (status); 100 : : } 101 : : 102 : : /* Release the write lock only for the very last reader */ 103 : : 104 : 210 : lock->num_readers--; 105 [ + - ]: 210 : if (lock->num_readers == 0) { 106 : 210 : acpi_os_release_mutex(lock->writer_mutex); 107 : : } 108 : : 109 : 210 : acpi_os_release_mutex(lock->reader_mutex); 110 : 210 : 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 : : 129 : 0 : acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock) 130 : : { 131 : 0 : acpi_status status; 132 : : 133 : 0 : status = acpi_os_acquire_mutex(lock->writer_mutex, ACPI_WAIT_FOREVER); 134 : 0 : return (status); 135 : : } 136 : : 137 : 0 : void acpi_ut_release_write_lock(struct acpi_rw_lock *lock) 138 : : { 139 : : 140 : 0 : acpi_os_release_mutex(lock->writer_mutex); 141 : 0 : }