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 |
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 | acpi_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 | |
42 | void 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 | |
71 | acpi_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 | |
93 | acpi_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 | |
129 | acpi_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 | |
137 | void acpi_ut_release_write_lock(struct acpi_rw_lock *lock) |
138 | { |
139 | |
140 | acpi_os_release_mutex(lock->writer_mutex); |
141 | } |
142 |