195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 28a335a23SBob Moore /****************************************************************************** 38a335a23SBob Moore * 48a335a23SBob Moore * Module Name: utlock - Reader/Writer lock interfaces 58a335a23SBob Moore * 6*612c2932SBob Moore * Copyright (C) 2000 - 2023, Intel Corp. 78a335a23SBob Moore * 895857638SErik Schmauss *****************************************************************************/ 98a335a23SBob Moore 108a335a23SBob Moore #include <acpi/acpi.h> 118a335a23SBob Moore #include "accommon.h" 128a335a23SBob Moore 138a335a23SBob Moore #define _COMPONENT ACPI_UTILITIES 148a335a23SBob Moore ACPI_MODULE_NAME("utlock") 158a335a23SBob Moore 168a335a23SBob Moore /******************************************************************************* 178a335a23SBob Moore * 188a335a23SBob Moore * FUNCTION: acpi_ut_create_rw_lock 198a335a23SBob Moore * acpi_ut_delete_rw_lock 208a335a23SBob Moore * 21ba494beeSBob Moore * PARAMETERS: lock - Pointer to a valid RW lock 228a335a23SBob Moore * 238a335a23SBob Moore * RETURN: Status 248a335a23SBob Moore * 258a335a23SBob Moore * DESCRIPTION: Reader/writer lock creation and deletion interfaces. 268a335a23SBob Moore * 278a335a23SBob Moore ******************************************************************************/ acpi_ut_create_rw_lock(struct acpi_rw_lock * lock)288a335a23SBob Mooreacpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock) 298a335a23SBob Moore { 308a335a23SBob Moore acpi_status status; 318a335a23SBob Moore 328a335a23SBob Moore lock->num_readers = 0; 338a335a23SBob Moore status = acpi_os_create_mutex(&lock->reader_mutex); 348a335a23SBob Moore if (ACPI_FAILURE(status)) { 359c0d7939SLv Zheng return (status); 368a335a23SBob Moore } 378a335a23SBob Moore 388a335a23SBob Moore status = acpi_os_create_mutex(&lock->writer_mutex); 399c0d7939SLv Zheng return (status); 408a335a23SBob Moore } 418a335a23SBob Moore acpi_ut_delete_rw_lock(struct acpi_rw_lock * lock)428a335a23SBob Moorevoid acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock) 438a335a23SBob Moore { 448a335a23SBob Moore 458a335a23SBob Moore acpi_os_delete_mutex(lock->reader_mutex); 468a335a23SBob Moore acpi_os_delete_mutex(lock->writer_mutex); 478a335a23SBob Moore 488a335a23SBob Moore lock->num_readers = 0; 498a335a23SBob Moore lock->reader_mutex = NULL; 508a335a23SBob Moore lock->writer_mutex = NULL; 518a335a23SBob Moore } 528a335a23SBob Moore 538a335a23SBob Moore /******************************************************************************* 548a335a23SBob Moore * 558a335a23SBob Moore * FUNCTION: acpi_ut_acquire_read_lock 568a335a23SBob Moore * acpi_ut_release_read_lock 578a335a23SBob Moore * 58ba494beeSBob Moore * PARAMETERS: lock - Pointer to a valid RW lock 598a335a23SBob Moore * 608a335a23SBob Moore * RETURN: Status 618a335a23SBob Moore * 628a335a23SBob Moore * DESCRIPTION: Reader interfaces for reader/writer locks. On acquisition, 638a335a23SBob Moore * only the first reader acquires the write mutex. On release, 648a335a23SBob Moore * only the last reader releases the write mutex. Although this 658a335a23SBob Moore * algorithm can in theory starve writers, this should not be a 668a335a23SBob Moore * problem with ACPICA since the subsystem is infrequently used 678a335a23SBob Moore * in comparison to (for example) an I/O system. 688a335a23SBob Moore * 698a335a23SBob Moore ******************************************************************************/ 708a335a23SBob Moore acpi_ut_acquire_read_lock(struct acpi_rw_lock * lock)718a335a23SBob Mooreacpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock) 728a335a23SBob Moore { 738a335a23SBob Moore acpi_status status; 748a335a23SBob Moore 758a335a23SBob Moore status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER); 768a335a23SBob Moore if (ACPI_FAILURE(status)) { 779c0d7939SLv Zheng return (status); 788a335a23SBob Moore } 798a335a23SBob Moore 808a335a23SBob Moore /* Acquire the write lock only for the first reader */ 818a335a23SBob Moore 828a335a23SBob Moore lock->num_readers++; 838a335a23SBob Moore if (lock->num_readers == 1) { 848a335a23SBob Moore status = 858a335a23SBob Moore acpi_os_acquire_mutex(lock->writer_mutex, 868a335a23SBob Moore ACPI_WAIT_FOREVER); 878a335a23SBob Moore } 888a335a23SBob Moore 898a335a23SBob Moore acpi_os_release_mutex(lock->reader_mutex); 909c0d7939SLv Zheng return (status); 918a335a23SBob Moore } 928a335a23SBob Moore acpi_ut_release_read_lock(struct acpi_rw_lock * lock)938a335a23SBob Mooreacpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock) 948a335a23SBob Moore { 958a335a23SBob Moore acpi_status status; 968a335a23SBob Moore 978a335a23SBob Moore status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER); 988a335a23SBob Moore if (ACPI_FAILURE(status)) { 999c0d7939SLv Zheng return (status); 1008a335a23SBob Moore } 1018a335a23SBob Moore 1028a335a23SBob Moore /* Release the write lock only for the very last reader */ 1038a335a23SBob Moore 1048a335a23SBob Moore lock->num_readers--; 1058a335a23SBob Moore if (lock->num_readers == 0) { 1068a335a23SBob Moore acpi_os_release_mutex(lock->writer_mutex); 1078a335a23SBob Moore } 1088a335a23SBob Moore 1098a335a23SBob Moore acpi_os_release_mutex(lock->reader_mutex); 1109c0d7939SLv Zheng return (status); 1118a335a23SBob Moore } 1128a335a23SBob Moore 1138a335a23SBob Moore /******************************************************************************* 1148a335a23SBob Moore * 1158a335a23SBob Moore * FUNCTION: acpi_ut_acquire_write_lock 1168a335a23SBob Moore * acpi_ut_release_write_lock 1178a335a23SBob Moore * 118ba494beeSBob Moore * PARAMETERS: lock - Pointer to a valid RW lock 1198a335a23SBob Moore * 1208a335a23SBob Moore * RETURN: Status 1218a335a23SBob Moore * 1228a335a23SBob Moore * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or 1238a335a23SBob Moore * release the writer mutex associated with the lock. Acquisition 1248a335a23SBob Moore * of the lock is fully exclusive and will block all readers and 1258a335a23SBob Moore * writers until it is released. 1268a335a23SBob Moore * 1278a335a23SBob Moore ******************************************************************************/ 1288a335a23SBob Moore acpi_ut_acquire_write_lock(struct acpi_rw_lock * lock)1298a335a23SBob Mooreacpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock) 1308a335a23SBob Moore { 1318a335a23SBob Moore acpi_status status; 1328a335a23SBob Moore 1338a335a23SBob Moore status = acpi_os_acquire_mutex(lock->writer_mutex, ACPI_WAIT_FOREVER); 1349c0d7939SLv Zheng return (status); 1358a335a23SBob Moore } 1368a335a23SBob Moore acpi_ut_release_write_lock(struct acpi_rw_lock * lock)1378a335a23SBob Moorevoid acpi_ut_release_write_lock(struct acpi_rw_lock *lock) 1388a335a23SBob Moore { 1398a335a23SBob Moore 1408a335a23SBob Moore acpi_os_release_mutex(lock->writer_mutex); 1418a335a23SBob Moore } 142