Linux Audio

Check our new training course

Loading...
  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 - 2023, 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}