xref: /freebsd/sys/contrib/dev/acpica/components/utilities/utlock.c (revision a159c266a93c3c4f229864954c5f963acd8f60f2)
1*a159c266SJung-uk Kim /******************************************************************************
2*a159c266SJung-uk Kim  *
3*a159c266SJung-uk Kim  * Module Name: utlock - Reader/Writer lock interfaces
4*a159c266SJung-uk Kim  *
5*a159c266SJung-uk Kim  *****************************************************************************/
6*a159c266SJung-uk Kim 
7*a159c266SJung-uk Kim /*
8*a159c266SJung-uk Kim  * Copyright (C) 2000 - 2012, Intel Corp.
9*a159c266SJung-uk Kim  * All rights reserved.
10*a159c266SJung-uk Kim  *
11*a159c266SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12*a159c266SJung-uk Kim  * modification, are permitted provided that the following conditions
13*a159c266SJung-uk Kim  * are met:
14*a159c266SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15*a159c266SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16*a159c266SJung-uk Kim  *    without modification.
17*a159c266SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*a159c266SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19*a159c266SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20*a159c266SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21*a159c266SJung-uk Kim  *    binary redistribution.
22*a159c266SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23*a159c266SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24*a159c266SJung-uk Kim  *    from this software without specific prior written permission.
25*a159c266SJung-uk Kim  *
26*a159c266SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27*a159c266SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28*a159c266SJung-uk Kim  * Software Foundation.
29*a159c266SJung-uk Kim  *
30*a159c266SJung-uk Kim  * NO WARRANTY
31*a159c266SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*a159c266SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*a159c266SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*a159c266SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*a159c266SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*a159c266SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*a159c266SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*a159c266SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*a159c266SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*a159c266SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*a159c266SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42*a159c266SJung-uk Kim  */
43*a159c266SJung-uk Kim 
44*a159c266SJung-uk Kim #define __UTLOCK_C__
45*a159c266SJung-uk Kim 
46*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
47*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
48*a159c266SJung-uk Kim 
49*a159c266SJung-uk Kim 
50*a159c266SJung-uk Kim #define _COMPONENT          ACPI_UTILITIES
51*a159c266SJung-uk Kim         ACPI_MODULE_NAME    ("utlock")
52*a159c266SJung-uk Kim 
53*a159c266SJung-uk Kim 
54*a159c266SJung-uk Kim /*******************************************************************************
55*a159c266SJung-uk Kim  *
56*a159c266SJung-uk Kim  * FUNCTION:    AcpiUtCreateRwLock
57*a159c266SJung-uk Kim  *              AcpiUtDeleteRwLock
58*a159c266SJung-uk Kim  *
59*a159c266SJung-uk Kim  * PARAMETERS:  Lock                - Pointer to a valid RW lock
60*a159c266SJung-uk Kim  *
61*a159c266SJung-uk Kim  * RETURN:      Status
62*a159c266SJung-uk Kim  *
63*a159c266SJung-uk Kim  * DESCRIPTION: Reader/writer lock creation and deletion interfaces.
64*a159c266SJung-uk Kim  *
65*a159c266SJung-uk Kim  ******************************************************************************/
66*a159c266SJung-uk Kim 
67*a159c266SJung-uk Kim ACPI_STATUS
68*a159c266SJung-uk Kim AcpiUtCreateRwLock (
69*a159c266SJung-uk Kim     ACPI_RW_LOCK            *Lock)
70*a159c266SJung-uk Kim {
71*a159c266SJung-uk Kim     ACPI_STATUS             Status;
72*a159c266SJung-uk Kim 
73*a159c266SJung-uk Kim 
74*a159c266SJung-uk Kim     Lock->NumReaders = 0;
75*a159c266SJung-uk Kim     Status = AcpiOsCreateMutex (&Lock->ReaderMutex);
76*a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
77*a159c266SJung-uk Kim     {
78*a159c266SJung-uk Kim         return (Status);
79*a159c266SJung-uk Kim     }
80*a159c266SJung-uk Kim 
81*a159c266SJung-uk Kim     Status = AcpiOsCreateMutex (&Lock->WriterMutex);
82*a159c266SJung-uk Kim     return (Status);
83*a159c266SJung-uk Kim }
84*a159c266SJung-uk Kim 
85*a159c266SJung-uk Kim 
86*a159c266SJung-uk Kim void
87*a159c266SJung-uk Kim AcpiUtDeleteRwLock (
88*a159c266SJung-uk Kim     ACPI_RW_LOCK            *Lock)
89*a159c266SJung-uk Kim {
90*a159c266SJung-uk Kim 
91*a159c266SJung-uk Kim     AcpiOsDeleteMutex (Lock->ReaderMutex);
92*a159c266SJung-uk Kim     AcpiOsDeleteMutex (Lock->WriterMutex);
93*a159c266SJung-uk Kim 
94*a159c266SJung-uk Kim     Lock->NumReaders = 0;
95*a159c266SJung-uk Kim     Lock->ReaderMutex = NULL;
96*a159c266SJung-uk Kim     Lock->WriterMutex = NULL;
97*a159c266SJung-uk Kim }
98*a159c266SJung-uk Kim 
99*a159c266SJung-uk Kim 
100*a159c266SJung-uk Kim /*******************************************************************************
101*a159c266SJung-uk Kim  *
102*a159c266SJung-uk Kim  * FUNCTION:    AcpiUtAcquireReadLock
103*a159c266SJung-uk Kim  *              AcpiUtReleaseReadLock
104*a159c266SJung-uk Kim  *
105*a159c266SJung-uk Kim  * PARAMETERS:  Lock                - Pointer to a valid RW lock
106*a159c266SJung-uk Kim  *
107*a159c266SJung-uk Kim  * RETURN:      Status
108*a159c266SJung-uk Kim  *
109*a159c266SJung-uk Kim  * DESCRIPTION: Reader interfaces for reader/writer locks. On acquisition,
110*a159c266SJung-uk Kim  *              only the first reader acquires the write mutex. On release,
111*a159c266SJung-uk Kim  *              only the last reader releases the write mutex. Although this
112*a159c266SJung-uk Kim  *              algorithm can in theory starve writers, this should not be a
113*a159c266SJung-uk Kim  *              problem with ACPICA since the subsystem is infrequently used
114*a159c266SJung-uk Kim  *              in comparison to (for example) an I/O system.
115*a159c266SJung-uk Kim  *
116*a159c266SJung-uk Kim  ******************************************************************************/
117*a159c266SJung-uk Kim 
118*a159c266SJung-uk Kim ACPI_STATUS
119*a159c266SJung-uk Kim AcpiUtAcquireReadLock (
120*a159c266SJung-uk Kim     ACPI_RW_LOCK            *Lock)
121*a159c266SJung-uk Kim {
122*a159c266SJung-uk Kim     ACPI_STATUS             Status;
123*a159c266SJung-uk Kim 
124*a159c266SJung-uk Kim 
125*a159c266SJung-uk Kim     Status = AcpiOsAcquireMutex (Lock->ReaderMutex, ACPI_WAIT_FOREVER);
126*a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
127*a159c266SJung-uk Kim     {
128*a159c266SJung-uk Kim         return (Status);
129*a159c266SJung-uk Kim     }
130*a159c266SJung-uk Kim 
131*a159c266SJung-uk Kim     /* Acquire the write lock only for the first reader */
132*a159c266SJung-uk Kim 
133*a159c266SJung-uk Kim     Lock->NumReaders++;
134*a159c266SJung-uk Kim     if (Lock->NumReaders == 1)
135*a159c266SJung-uk Kim     {
136*a159c266SJung-uk Kim         Status = AcpiOsAcquireMutex (Lock->WriterMutex, ACPI_WAIT_FOREVER);
137*a159c266SJung-uk Kim     }
138*a159c266SJung-uk Kim 
139*a159c266SJung-uk Kim     AcpiOsReleaseMutex (Lock->ReaderMutex);
140*a159c266SJung-uk Kim     return (Status);
141*a159c266SJung-uk Kim }
142*a159c266SJung-uk Kim 
143*a159c266SJung-uk Kim 
144*a159c266SJung-uk Kim ACPI_STATUS
145*a159c266SJung-uk Kim AcpiUtReleaseReadLock (
146*a159c266SJung-uk Kim     ACPI_RW_LOCK            *Lock)
147*a159c266SJung-uk Kim {
148*a159c266SJung-uk Kim     ACPI_STATUS             Status;
149*a159c266SJung-uk Kim 
150*a159c266SJung-uk Kim 
151*a159c266SJung-uk Kim     Status = AcpiOsAcquireMutex (Lock->ReaderMutex, ACPI_WAIT_FOREVER);
152*a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
153*a159c266SJung-uk Kim     {
154*a159c266SJung-uk Kim         return (Status);
155*a159c266SJung-uk Kim     }
156*a159c266SJung-uk Kim 
157*a159c266SJung-uk Kim     /* Release the write lock only for the very last reader */
158*a159c266SJung-uk Kim 
159*a159c266SJung-uk Kim     Lock->NumReaders--;
160*a159c266SJung-uk Kim     if (Lock->NumReaders == 0)
161*a159c266SJung-uk Kim     {
162*a159c266SJung-uk Kim         AcpiOsReleaseMutex (Lock->WriterMutex);
163*a159c266SJung-uk Kim     }
164*a159c266SJung-uk Kim 
165*a159c266SJung-uk Kim     AcpiOsReleaseMutex (Lock->ReaderMutex);
166*a159c266SJung-uk Kim     return (Status);
167*a159c266SJung-uk Kim }
168*a159c266SJung-uk Kim 
169*a159c266SJung-uk Kim 
170*a159c266SJung-uk Kim /*******************************************************************************
171*a159c266SJung-uk Kim  *
172*a159c266SJung-uk Kim  * FUNCTION:    AcpiUtAcquireWriteLock
173*a159c266SJung-uk Kim  *              AcpiUtReleaseWriteLock
174*a159c266SJung-uk Kim  *
175*a159c266SJung-uk Kim  * PARAMETERS:  Lock                - Pointer to a valid RW lock
176*a159c266SJung-uk Kim  *
177*a159c266SJung-uk Kim  * RETURN:      Status
178*a159c266SJung-uk Kim  *
179*a159c266SJung-uk Kim  * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or
180*a159c266SJung-uk Kim  *              release the writer mutex associated with the lock. Acquisition
181*a159c266SJung-uk Kim  *              of the lock is fully exclusive and will block all readers and
182*a159c266SJung-uk Kim  *              writers until it is released.
183*a159c266SJung-uk Kim  *
184*a159c266SJung-uk Kim  ******************************************************************************/
185*a159c266SJung-uk Kim 
186*a159c266SJung-uk Kim ACPI_STATUS
187*a159c266SJung-uk Kim AcpiUtAcquireWriteLock (
188*a159c266SJung-uk Kim     ACPI_RW_LOCK            *Lock)
189*a159c266SJung-uk Kim {
190*a159c266SJung-uk Kim     ACPI_STATUS             Status;
191*a159c266SJung-uk Kim 
192*a159c266SJung-uk Kim 
193*a159c266SJung-uk Kim     Status = AcpiOsAcquireMutex (Lock->WriterMutex, ACPI_WAIT_FOREVER);
194*a159c266SJung-uk Kim     return (Status);
195*a159c266SJung-uk Kim }
196*a159c266SJung-uk Kim 
197*a159c266SJung-uk Kim 
198*a159c266SJung-uk Kim void
199*a159c266SJung-uk Kim AcpiUtReleaseWriteLock (
200*a159c266SJung-uk Kim     ACPI_RW_LOCK            *Lock)
201*a159c266SJung-uk Kim {
202*a159c266SJung-uk Kim 
203*a159c266SJung-uk Kim     AcpiOsReleaseMutex (Lock->WriterMutex);
204*a159c266SJung-uk Kim }
205*a159c266SJung-uk Kim 
206