142 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/******************************************************************************3 *4 * Module Name: utlock - Reader/Writer lock interfaces5 *6 * Copyright (C) 2000 - 2023, Intel Corp.7 *8 *****************************************************************************/9 10#include <acpi/acpi.h>11#include "accommon.h"12 13#define _COMPONENT ACPI_UTILITIES14ACPI_MODULE_NAME("utlock")15 16/*******************************************************************************17 *18 * FUNCTION: acpi_ut_create_rw_lock19 * acpi_ut_delete_rw_lock20 *21 * PARAMETERS: lock - Pointer to a valid RW lock22 *23 * RETURN: Status24 *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_lock56 * acpi_ut_release_read_lock57 *58 * PARAMETERS: lock - Pointer to a valid RW lock59 *60 * RETURN: Status61 *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 this65 * algorithm can in theory starve writers, this should not be a66 * problem with ACPICA since the subsystem is infrequently used67 * 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_lock116 * acpi_ut_release_write_lock117 *118 * PARAMETERS: lock - Pointer to a valid RW lock119 *120 * RETURN: Status121 *122 * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or123 * release the writer mutex associated with the lock. Acquisition124 * of the lock is fully exclusive and will block all readers and125 * 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