1 /*******************************************************************************
2 *
3 * Module Name: utmutex - local mutex support
4 *
5 ******************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
79 void)
80 {
81 UINT32 i;
82 ACPI_STATUS Status;
83
84
85 ACPI_FUNCTION_TRACE (UtMutexInitialize);
86
87
88 /* Create each of the predefined mutex objects */
89
90 for (i = 0; i < ACPI_NUM_MUTEX; i++)
91 {
92 Status = AcpiUtCreateMutex (i);
93 if (ACPI_FAILURE (Status))
94 {
95 return_ACPI_STATUS (Status);
96 }
97 }
98
99 /* Create the spinlocks for use at interrupt level */
100
101 Status = AcpiOsCreateLock (&AcpiGbl_GpeLock);
102 if (ACPI_FAILURE (Status))
103 {
104 return_ACPI_STATUS (Status);
105 }
106
107 Status = AcpiOsCreateLock (&AcpiGbl_HardwareLock);
108 if (ACPI_FAILURE (Status))
109 {
110 return_ACPI_STATUS (Status);
111 }
112
113 /* Mutex for _OSI support */
114 Status = AcpiOsCreateMutex (&AcpiGbl_OsiMutex);
115 if (ACPI_FAILURE (Status))
116 {
117 return_ACPI_STATUS (Status);
118 }
119
120 /* Create the reader/writer lock for namespace access */
121
122 Status = AcpiUtCreateRwLock (&AcpiGbl_NamespaceRwLock);
123 return_ACPI_STATUS (Status);
124 }
125
126
127 /*******************************************************************************
128 *
129 * FUNCTION: AcpiUtMutexTerminate
130 *
131 * PARAMETERS: None.
132 *
133 * RETURN: None.
143 {
144 UINT32 i;
145
146
147 ACPI_FUNCTION_TRACE (UtMutexTerminate);
148
149
150 /* Delete each predefined mutex object */
151
152 for (i = 0; i < ACPI_NUM_MUTEX; i++)
153 {
154 AcpiUtDeleteMutex (i);
155 }
156
157 AcpiOsDeleteMutex (AcpiGbl_OsiMutex);
158
159 /* Delete the spinlocks */
160
161 AcpiOsDeleteLock (AcpiGbl_GpeLock);
162 AcpiOsDeleteLock (AcpiGbl_HardwareLock);
163
164 /* Delete the reader/writer lock */
165
166 AcpiUtDeleteRwLock (&AcpiGbl_NamespaceRwLock);
167 return_VOID;
168 }
169
170
171 /*******************************************************************************
172 *
173 * FUNCTION: AcpiUtCreateMutex
174 *
175 * PARAMETERS: MutexID - ID of the mutex to be created
176 *
177 * RETURN: Status
178 *
179 * DESCRIPTION: Create a mutex object.
180 *
181 ******************************************************************************/
182
208 * PARAMETERS: MutexID - ID of the mutex to be deleted
209 *
210 * RETURN: Status
211 *
212 * DESCRIPTION: Delete a mutex object.
213 *
214 ******************************************************************************/
215
216 static void
217 AcpiUtDeleteMutex (
218 ACPI_MUTEX_HANDLE MutexId)
219 {
220
221 ACPI_FUNCTION_TRACE_U32 (UtDeleteMutex, MutexId);
222
223
224 AcpiOsDeleteMutex (AcpiGbl_MutexInfo[MutexId].Mutex);
225
226 AcpiGbl_MutexInfo[MutexId].Mutex = NULL;
227 AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED;
228 }
229
230
231 /*******************************************************************************
232 *
233 * FUNCTION: AcpiUtAcquireMutex
234 *
235 * PARAMETERS: MutexID - ID of the mutex to be acquired
236 *
237 * RETURN: Status
238 *
239 * DESCRIPTION: Acquire a mutex object.
240 *
241 ******************************************************************************/
242
243 ACPI_STATUS
244 AcpiUtAcquireMutex (
245 ACPI_MUTEX_HANDLE MutexId)
246 {
247 ACPI_STATUS Status;
318 return (Status);
319 }
320
321
322 /*******************************************************************************
323 *
324 * FUNCTION: AcpiUtReleaseMutex
325 *
326 * PARAMETERS: MutexID - ID of the mutex to be released
327 *
328 * RETURN: Status
329 *
330 * DESCRIPTION: Release a mutex object.
331 *
332 ******************************************************************************/
333
334 ACPI_STATUS
335 AcpiUtReleaseMutex (
336 ACPI_MUTEX_HANDLE MutexId)
337 {
338 ACPI_THREAD_ID ThisThreadId;
339
340
341 ACPI_FUNCTION_NAME (UtReleaseMutex);
342
343
344 ThisThreadId = AcpiOsGetThreadId ();
345 ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n",
346 (UINT32) ThisThreadId, AcpiUtGetMutexName (MutexId)));
347
348 if (MutexId > ACPI_MAX_MUTEX)
349 {
350 return (AE_BAD_PARAMETER);
351 }
352
353 /*
354 * Mutex must be acquired in order to release it!
355 */
356 if (AcpiGbl_MutexInfo[MutexId].ThreadId == ACPI_MUTEX_NOT_ACQUIRED)
357 {
358 ACPI_ERROR ((AE_INFO,
359 "Mutex [0x%X] is not acquired, cannot release", MutexId));
360
361 return (AE_NOT_ACQUIRED);
362 }
363
364 #ifdef ACPI_MUTEX_DEBUG
365 {
366 UINT32 i;
367 /*
368 * Mutex debug code, for internal debugging only.
369 *
370 * Deadlock prevention. Check if this thread owns any mutexes of value
371 * greater than this one. If so, the thread has violated the mutex
372 * ordering rule. This indicates a coding error somewhere in
373 * the ACPI subsystem code.
374 */
375 for (i = MutexId; i < ACPI_NUM_MUTEX; i++)
376 {
377 if (AcpiGbl_MutexInfo[i].ThreadId == ThisThreadId)
378 {
379 if (i == MutexId)
380 {
381 continue;
382 }
383
384 ACPI_ERROR ((AE_INFO,
385 "Invalid release order: owns [%s], releasing [%s]",
386 AcpiUtGetMutexName (i), AcpiUtGetMutexName (MutexId)));
387
388 return (AE_RELEASE_DEADLOCK);
389 }
390 }
391 }
392 #endif
393
394 /* Mark unlocked FIRST */
395
396 AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED;
397
398 AcpiOsReleaseMutex (AcpiGbl_MutexInfo[MutexId].Mutex);
399 return (AE_OK);
400 }
401
402
|
1 /*******************************************************************************
2 *
3 * Module Name: utmutex - local mutex support
4 *
5 ******************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2014, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
79 void)
80 {
81 UINT32 i;
82 ACPI_STATUS Status;
83
84
85 ACPI_FUNCTION_TRACE (UtMutexInitialize);
86
87
88 /* Create each of the predefined mutex objects */
89
90 for (i = 0; i < ACPI_NUM_MUTEX; i++)
91 {
92 Status = AcpiUtCreateMutex (i);
93 if (ACPI_FAILURE (Status))
94 {
95 return_ACPI_STATUS (Status);
96 }
97 }
98
99 /* Create the spinlocks for use at interrupt level or for speed */
100
101 Status = AcpiOsCreateLock (&AcpiGbl_GpeLock);
102 if (ACPI_FAILURE (Status))
103 {
104 return_ACPI_STATUS (Status);
105 }
106
107 Status = AcpiOsCreateLock (&AcpiGbl_HardwareLock);
108 if (ACPI_FAILURE (Status))
109 {
110 return_ACPI_STATUS (Status);
111 }
112
113 Status = AcpiOsCreateLock (&AcpiGbl_ReferenceCountLock);
114 if (ACPI_FAILURE (Status))
115 {
116 return_ACPI_STATUS (Status);
117 }
118
119 /* Mutex for _OSI support */
120
121 Status = AcpiOsCreateMutex (&AcpiGbl_OsiMutex);
122 if (ACPI_FAILURE (Status))
123 {
124 return_ACPI_STATUS (Status);
125 }
126
127 /* Create the reader/writer lock for namespace access */
128
129 Status = AcpiUtCreateRwLock (&AcpiGbl_NamespaceRwLock);
130 return_ACPI_STATUS (Status);
131 }
132
133
134 /*******************************************************************************
135 *
136 * FUNCTION: AcpiUtMutexTerminate
137 *
138 * PARAMETERS: None.
139 *
140 * RETURN: None.
150 {
151 UINT32 i;
152
153
154 ACPI_FUNCTION_TRACE (UtMutexTerminate);
155
156
157 /* Delete each predefined mutex object */
158
159 for (i = 0; i < ACPI_NUM_MUTEX; i++)
160 {
161 AcpiUtDeleteMutex (i);
162 }
163
164 AcpiOsDeleteMutex (AcpiGbl_OsiMutex);
165
166 /* Delete the spinlocks */
167
168 AcpiOsDeleteLock (AcpiGbl_GpeLock);
169 AcpiOsDeleteLock (AcpiGbl_HardwareLock);
170 AcpiOsDeleteLock (AcpiGbl_ReferenceCountLock);
171
172 /* Delete the reader/writer lock */
173
174 AcpiUtDeleteRwLock (&AcpiGbl_NamespaceRwLock);
175 return_VOID;
176 }
177
178
179 /*******************************************************************************
180 *
181 * FUNCTION: AcpiUtCreateMutex
182 *
183 * PARAMETERS: MutexID - ID of the mutex to be created
184 *
185 * RETURN: Status
186 *
187 * DESCRIPTION: Create a mutex object.
188 *
189 ******************************************************************************/
190
216 * PARAMETERS: MutexID - ID of the mutex to be deleted
217 *
218 * RETURN: Status
219 *
220 * DESCRIPTION: Delete a mutex object.
221 *
222 ******************************************************************************/
223
224 static void
225 AcpiUtDeleteMutex (
226 ACPI_MUTEX_HANDLE MutexId)
227 {
228
229 ACPI_FUNCTION_TRACE_U32 (UtDeleteMutex, MutexId);
230
231
232 AcpiOsDeleteMutex (AcpiGbl_MutexInfo[MutexId].Mutex);
233
234 AcpiGbl_MutexInfo[MutexId].Mutex = NULL;
235 AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED;
236
237 return_VOID;
238 }
239
240
241 /*******************************************************************************
242 *
243 * FUNCTION: AcpiUtAcquireMutex
244 *
245 * PARAMETERS: MutexID - ID of the mutex to be acquired
246 *
247 * RETURN: Status
248 *
249 * DESCRIPTION: Acquire a mutex object.
250 *
251 ******************************************************************************/
252
253 ACPI_STATUS
254 AcpiUtAcquireMutex (
255 ACPI_MUTEX_HANDLE MutexId)
256 {
257 ACPI_STATUS Status;
328 return (Status);
329 }
330
331
332 /*******************************************************************************
333 *
334 * FUNCTION: AcpiUtReleaseMutex
335 *
336 * PARAMETERS: MutexID - ID of the mutex to be released
337 *
338 * RETURN: Status
339 *
340 * DESCRIPTION: Release a mutex object.
341 *
342 ******************************************************************************/
343
344 ACPI_STATUS
345 AcpiUtReleaseMutex (
346 ACPI_MUTEX_HANDLE MutexId)
347 {
348 ACPI_FUNCTION_NAME (UtReleaseMutex);
349
350
351 ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n",
352 (UINT32) AcpiOsGetThreadId (), AcpiUtGetMutexName (MutexId)));
353
354 if (MutexId > ACPI_MAX_MUTEX)
355 {
356 return (AE_BAD_PARAMETER);
357 }
358
359 /*
360 * Mutex must be acquired in order to release it!
361 */
362 if (AcpiGbl_MutexInfo[MutexId].ThreadId == ACPI_MUTEX_NOT_ACQUIRED)
363 {
364 ACPI_ERROR ((AE_INFO,
365 "Mutex [0x%X] is not acquired, cannot release", MutexId));
366
367 return (AE_NOT_ACQUIRED);
368 }
369
370 #ifdef ACPI_MUTEX_DEBUG
371 {
372 UINT32 i;
373 /*
374 * Mutex debug code, for internal debugging only.
375 *
376 * Deadlock prevention. Check if this thread owns any mutexes of value
377 * greater than this one. If so, the thread has violated the mutex
378 * ordering rule. This indicates a coding error somewhere in
379 * the ACPI subsystem code.
380 */
381 for (i = MutexId; i < ACPI_NUM_MUTEX; i++)
382 {
383 if (AcpiGbl_MutexInfo[i].ThreadId == AcpiOsGetThreadId ())
384 {
385 if (i == MutexId)
386 {
387 continue;
388 }
389
390 ACPI_ERROR ((AE_INFO,
391 "Invalid release order: owns [%s], releasing [%s]",
392 AcpiUtGetMutexName (i), AcpiUtGetMutexName (MutexId)));
393
394 return (AE_RELEASE_DEADLOCK);
395 }
396 }
397 }
398 #endif
399
400 /* Mark unlocked FIRST */
401
402 AcpiGbl_MutexInfo[MutexId].ThreadId = ACPI_MUTEX_NOT_ACQUIRED;
403
404 AcpiOsReleaseMutex (AcpiGbl_MutexInfo[MutexId].Mutex);
405 return (AE_OK);
406 }
|