/******************************************************************************* * * FUNCTION: acpi_acquire_global_lock * * PARAMETERS: Timeout - How long the caller is willing to wait * Handle - Where the handle to the lock is returned * (if acquired) * * RETURN: Status * * DESCRIPTION: Acquire the ACPI Global Lock * * Note: Allows callers with the same thread ID to acquire the global lock * multiple times. In other words, externally, the behavior of the global lock * is identical to an AML mutex. On the first acquire, a new handle is * returned. On any subsequent calls to acquire by the same thread, the same * handle is returned. * ******************************************************************************/ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle) { acpi_status status; if (!handle) { return (AE_BAD_PARAMETER); } /* Must lock interpreter to prevent race conditions */ acpi_ex_enter_interpreter(); status = acpi_ex_acquire_mutex_object(timeout, acpi_gbl_global_lock_mutex, acpi_os_get_thread_id()); if (ACPI_SUCCESS(status)) { /* Return the global lock handle (updated in acpi_ev_acquire_global_lock) */ *handle = acpi_gbl_global_lock_handle; } acpi_ex_exit_interpreter(); return (status); }
acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle) { acpi_status status; if (!handle) { return (AE_BAD_PARAMETER); } acpi_ex_enter_interpreter(); status = acpi_ex_acquire_mutex_object(timeout, acpi_gbl_global_lock_mutex, acpi_os_get_thread_id()); if (ACPI_SUCCESS(status)) { *handle = acpi_gbl_global_lock_handle; } acpi_ex_exit_interpreter(); return (status); }
acpi_status acpi_ex_acquire_mutex(union acpi_operand_object *time_desc, union acpi_operand_object *obj_desc, struct acpi_walk_state *walk_state) { acpi_status status; ACPI_FUNCTION_TRACE_PTR(ex_acquire_mutex, obj_desc); if (!obj_desc) { return_ACPI_STATUS(AE_BAD_PARAMETER); } /* Must have a valid thread ID */ if (!walk_state->thread) { ACPI_ERROR((AE_INFO, "Cannot acquire Mutex [%4.4s], null thread info", acpi_ut_get_node_name(obj_desc->mutex.node))); return_ACPI_STATUS(AE_AML_INTERNAL); } /* * Current sync level must be less than or equal to the sync level of the * mutex. This mechanism provides some deadlock prevention */ if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) { ACPI_ERROR((AE_INFO, "Cannot acquire Mutex [%4.4s], current SyncLevel is too large (%d)", acpi_ut_get_node_name(obj_desc->mutex.node), walk_state->thread->current_sync_level)); return_ACPI_STATUS(AE_AML_MUTEX_ORDER); } status = acpi_ex_acquire_mutex_object((u16) time_desc->integer.value, obj_desc, walk_state->thread->thread_id); if (ACPI_SUCCESS(status) && obj_desc->mutex.acquisition_depth == 1) { /* Save Thread object, original/current sync levels */ obj_desc->mutex.owner_thread = walk_state->thread; obj_desc->mutex.original_sync_level = walk_state->thread->current_sync_level; walk_state->thread->current_sync_level = obj_desc->mutex.sync_level; /* Link the mutex to the current thread for force-unlock at method exit */ acpi_ex_link_mutex(obj_desc, walk_state->thread); } return_ACPI_STATUS(status); }