0001
0002
0003
0004
0005
0006
0007
0008 #include <acpi/acpi.h>
0009 #include "accommon.h"
0010
0011 #define _COMPONENT ACPI_UTILITIES
0012 ACPI_MODULE_NAME("utmutex")
0013
0014
0015 static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id);
0016
0017 static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id);
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 acpi_status acpi_ut_mutex_initialize(void)
0033 {
0034 u32 i;
0035 acpi_status status;
0036
0037 ACPI_FUNCTION_TRACE(ut_mutex_initialize);
0038
0039
0040
0041 for (i = 0; i < ACPI_NUM_MUTEX; i++) {
0042 status = acpi_ut_create_mutex(i);
0043 if (ACPI_FAILURE(status)) {
0044 return_ACPI_STATUS(status);
0045 }
0046 }
0047
0048
0049
0050 status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
0051 if (ACPI_FAILURE (status)) {
0052 return_ACPI_STATUS (status);
0053 }
0054
0055 status = acpi_os_create_raw_lock(&acpi_gbl_hardware_lock);
0056 if (ACPI_FAILURE (status)) {
0057 return_ACPI_STATUS (status);
0058 }
0059
0060 status = acpi_os_create_lock(&acpi_gbl_reference_count_lock);
0061 if (ACPI_FAILURE(status)) {
0062 return_ACPI_STATUS(status);
0063 }
0064
0065
0066
0067 status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
0068 if (ACPI_FAILURE(status)) {
0069 return_ACPI_STATUS(status);
0070 }
0071
0072
0073
0074 status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
0075 if (ACPI_FAILURE(status)) {
0076 return_ACPI_STATUS(status);
0077 }
0078
0079 return_ACPI_STATUS(status);
0080 }
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 void acpi_ut_mutex_terminate(void)
0096 {
0097 u32 i;
0098
0099 ACPI_FUNCTION_TRACE(ut_mutex_terminate);
0100
0101
0102
0103 for (i = 0; i < ACPI_NUM_MUTEX; i++) {
0104 acpi_ut_delete_mutex(i);
0105 }
0106
0107 acpi_os_delete_mutex(acpi_gbl_osi_mutex);
0108
0109
0110
0111 acpi_os_delete_lock(acpi_gbl_gpe_lock);
0112 acpi_os_delete_raw_lock(acpi_gbl_hardware_lock);
0113 acpi_os_delete_lock(acpi_gbl_reference_count_lock);
0114
0115
0116
0117 acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
0118 return_VOID;
0119 }
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id)
0134 {
0135 acpi_status status = AE_OK;
0136
0137 ACPI_FUNCTION_TRACE_U32(ut_create_mutex, mutex_id);
0138
0139 if (!acpi_gbl_mutex_info[mutex_id].mutex) {
0140 status =
0141 acpi_os_create_mutex(&acpi_gbl_mutex_info[mutex_id].mutex);
0142 acpi_gbl_mutex_info[mutex_id].thread_id =
0143 ACPI_MUTEX_NOT_ACQUIRED;
0144 acpi_gbl_mutex_info[mutex_id].use_count = 0;
0145 }
0146
0147 return_ACPI_STATUS(status);
0148 }
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162 static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id)
0163 {
0164
0165 ACPI_FUNCTION_TRACE_U32(ut_delete_mutex, mutex_id);
0166
0167 acpi_os_delete_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
0168
0169 acpi_gbl_mutex_info[mutex_id].mutex = NULL;
0170 acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
0171
0172 return_VOID;
0173 }
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187 acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
0188 {
0189 acpi_status status;
0190 acpi_thread_id this_thread_id;
0191
0192 ACPI_FUNCTION_NAME(ut_acquire_mutex);
0193
0194 if (mutex_id > ACPI_MAX_MUTEX) {
0195 return (AE_BAD_PARAMETER);
0196 }
0197
0198 this_thread_id = acpi_os_get_thread_id();
0199
0200 #ifdef ACPI_MUTEX_DEBUG
0201 {
0202 u32 i;
0203
0204
0205
0206
0207
0208
0209
0210
0211 for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
0212 if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
0213 if (i == mutex_id) {
0214 ACPI_ERROR((AE_INFO,
0215 "Mutex [%s] already acquired by this thread [%u]",
0216 acpi_ut_get_mutex_name
0217 (mutex_id),
0218 (u32)this_thread_id));
0219
0220 return (AE_ALREADY_ACQUIRED);
0221 }
0222
0223 ACPI_ERROR((AE_INFO,
0224 "Invalid acquire order: Thread %u owns [%s], wants [%s]",
0225 (u32)this_thread_id,
0226 acpi_ut_get_mutex_name(i),
0227 acpi_ut_get_mutex_name(mutex_id)));
0228
0229 return (AE_ACQUIRE_DEADLOCK);
0230 }
0231 }
0232 }
0233 #endif
0234
0235 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
0236 "Thread %u attempting to acquire Mutex [%s]\n",
0237 (u32)this_thread_id,
0238 acpi_ut_get_mutex_name(mutex_id)));
0239
0240 status =
0241 acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
0242 ACPI_WAIT_FOREVER);
0243 if (ACPI_SUCCESS(status)) {
0244 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
0245 "Thread %u acquired Mutex [%s]\n",
0246 (u32)this_thread_id,
0247 acpi_ut_get_mutex_name(mutex_id)));
0248
0249 acpi_gbl_mutex_info[mutex_id].use_count++;
0250 acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
0251 } else {
0252 ACPI_EXCEPTION((AE_INFO, status,
0253 "Thread %u could not acquire Mutex [%s] (0x%X)",
0254 (u32)this_thread_id,
0255 acpi_ut_get_mutex_name(mutex_id), mutex_id));
0256 }
0257
0258 return (status);
0259 }
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273 acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
0274 {
0275 ACPI_FUNCTION_NAME(ut_release_mutex);
0276
0277 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n",
0278 (u32)acpi_os_get_thread_id(),
0279 acpi_ut_get_mutex_name(mutex_id)));
0280
0281 if (mutex_id > ACPI_MAX_MUTEX) {
0282 return (AE_BAD_PARAMETER);
0283 }
0284
0285
0286
0287
0288 if (acpi_gbl_mutex_info[mutex_id].thread_id == ACPI_MUTEX_NOT_ACQUIRED) {
0289 ACPI_ERROR((AE_INFO,
0290 "Mutex [%s] (0x%X) is not acquired, cannot release",
0291 acpi_ut_get_mutex_name(mutex_id), mutex_id));
0292
0293 return (AE_NOT_ACQUIRED);
0294 }
0295 #ifdef ACPI_MUTEX_DEBUG
0296 {
0297 u32 i;
0298
0299
0300
0301
0302
0303
0304
0305
0306 for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
0307 if (acpi_gbl_mutex_info[i].thread_id ==
0308 acpi_os_get_thread_id()) {
0309 if (i == mutex_id) {
0310 continue;
0311 }
0312
0313 ACPI_ERROR((AE_INFO,
0314 "Invalid release order: owns [%s], releasing [%s]",
0315 acpi_ut_get_mutex_name(i),
0316 acpi_ut_get_mutex_name(mutex_id)));
0317
0318 return (AE_RELEASE_DEADLOCK);
0319 }
0320 }
0321 }
0322 #endif
0323
0324
0325
0326 acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
0327
0328 acpi_os_release_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
0329 return (AE_OK);
0330 }