acpi_status acpi_ex_system_acquire_mutex ( union acpi_operand_object *time_desc, union acpi_operand_object *obj_desc) { acpi_status status = AE_OK; ACPI_FUNCTION_TRACE_PTR ("ex_system_acquire_mutex", obj_desc); if (!obj_desc) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* * Support for the _GL_ Mutex object -- go get the global lock */ if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) { status = acpi_ev_acquire_global_lock ((u16) time_desc->integer.value); return_ACPI_STATUS (status); } status = acpi_ex_system_wait_semaphore (obj_desc->mutex.semaphore, (u16) time_desc->integer.value); return_ACPI_STATUS (status); }
acpi_status acpi_ev_acquire_global_lock(u16 timeout) { acpi_cpu_flags flags; acpi_status status; u8 acquired = FALSE; ACPI_FUNCTION_TRACE(ev_acquire_global_lock); status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex->mutex. os_mutex, timeout); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } acpi_gbl_global_lock_handle++; if (acpi_gbl_global_lock_handle == 0) { acpi_gbl_global_lock_handle = 1; } if (!acpi_gbl_global_lock_present) { acpi_gbl_global_lock_acquired = TRUE; return_ACPI_STATUS(AE_OK); } flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock); do { ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); if (acquired) { acpi_gbl_global_lock_acquired = TRUE; ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Acquired hardware Global Lock\n")); break; } acpi_gbl_global_lock_pending = TRUE; acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags); ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n")); status = acpi_ex_system_wait_semaphore (acpi_gbl_global_lock_semaphore, ACPI_WAIT_FOREVER); flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock); } while (ACPI_SUCCESS(status)); acpi_gbl_global_lock_pending = FALSE; acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags); return_ACPI_STATUS(status); }
acpi_status acpi_ev_acquire_global_lock ( u16 timeout) { acpi_status status = AE_OK; u8 acquired = FALSE; ACPI_FUNCTION_TRACE ("ev_acquire_global_lock"); #ifndef ACPI_APPLICATION /* Make sure that we actually have a global lock */ if (!acpi_gbl_global_lock_present) { return_ACPI_STATUS (AE_NO_GLOBAL_LOCK); } #endif /* One more thread wants the global lock */ acpi_gbl_global_lock_thread_count++; /* * If we (OS side vs. BIOS side) have the hardware lock already, * we are done */ if (acpi_gbl_global_lock_acquired) { return_ACPI_STATUS (AE_OK); } /* We must acquire the actual hardware lock */ ACPI_ACQUIRE_GLOBAL_LOCK (acpi_gbl_common_fACS.global_lock, acquired); if (acquired) { /* We got the lock */ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Acquired the HW Global Lock\n")); acpi_gbl_global_lock_acquired = TRUE; return_ACPI_STATUS (AE_OK); } /* * Did not get the lock. The pending bit was set above, and we must now * wait until we get the global lock released interrupt. */ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Waiting for the HW Global Lock\n")); /* * Acquire the global lock semaphore first. * Since this wait will block, we must release the interpreter */ status = acpi_ex_system_wait_semaphore (acpi_gbl_global_lock_semaphore, timeout); return_ACPI_STATUS (status); }
acpi_status acpi_ds_begin_method_execution ( struct acpi_namespace_node *method_node, union acpi_operand_object *obj_desc, struct acpi_namespace_node *calling_method_node) { acpi_status status = AE_OK; ACPI_FUNCTION_TRACE_PTR ("ds_begin_method_execution", method_node); if (!method_node) { return_ACPI_STATUS (AE_NULL_ENTRY); } /* * If there is a concurrency limit on this method, we need to * obtain a unit from the method semaphore. */ if (obj_desc->method.semaphore) { /* * Allow recursive method calls, up to the reentrancy/concurrency * limit imposed by the SERIALIZED rule and the sync_level method * parameter. * * The point of this code is to avoid permanently blocking a * thread that is making recursive method calls. */ if (method_node == calling_method_node) { if (obj_desc->method.thread_count >= obj_desc->method.concurrency) { return_ACPI_STATUS (AE_AML_METHOD_LIMIT); } } /* * Get a unit from the method semaphore. This releases the * interpreter if we block */ status = acpi_ex_system_wait_semaphore (obj_desc->method.semaphore, ACPI_WAIT_FOREVER); } /* * Increment the method parse tree thread count since it has been * reentered one more time (even if it is the same thread) */ obj_desc->method.thread_count++; return_ACPI_STATUS (status); }
acpi_status acpi_ex_system_wait_event(union acpi_operand_object *time_desc, union acpi_operand_object *obj_desc) { acpi_status status = AE_OK; ACPI_FUNCTION_TRACE(ex_system_wait_event); if (obj_desc) { status = acpi_ex_system_wait_semaphore(obj_desc->event.os_semaphore, (u16) time_desc->integer. value); } return_ACPI_STATUS(status); }
acpi_status acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, union acpi_operand_object *obj_desc, struct acpi_namespace_node *calling_method_node) { acpi_status status = AE_OK; ACPI_FUNCTION_TRACE_PTR("ds_begin_method_execution", method_node); if (!method_node) { return_ACPI_STATUS(AE_NULL_ENTRY); } /* Prevent wraparound of thread count */ if (obj_desc->method.thread_count == ACPI_UINT8_MAX) { ACPI_REPORT_ERROR(("Method reached maximum reentrancy limit (255)\n")); return_ACPI_STATUS(AE_AML_METHOD_LIMIT); } /* * If there is a concurrency limit on this method, we need to * obtain a unit from the method semaphore. */ if (obj_desc->method.semaphore) { /* * Allow recursive method calls, up to the reentrancy/concurrency * limit imposed by the SERIALIZED rule and the sync_level method * parameter. * * The point of this code is to avoid permanently blocking a * thread that is making recursive method calls. */ if (method_node == calling_method_node) { if (obj_desc->method.thread_count >= obj_desc->method.concurrency) { return_ACPI_STATUS(AE_AML_METHOD_LIMIT); } } /* * Get a unit from the method semaphore. This releases the * interpreter if we block */ status = acpi_ex_system_wait_semaphore(obj_desc->method.semaphore, ACPI_WAIT_FOREVER); } /* * Allocate an Owner ID for this method, only if this is the first thread * to begin concurrent execution. We only need one owner_id, even if the * method is invoked recursively. */ if (!obj_desc->method.owner_id) { status = acpi_ut_allocate_owner_id(&obj_desc->method.owner_id); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } } /* * Increment the method parse tree thread count since it has been * reentered one more time (even if it is the same thread) */ obj_desc->method.thread_count++; return_ACPI_STATUS(status); }
acpi_status acpi_ev_acquire_global_lock(u16 timeout) { acpi_cpu_flags flags; acpi_status status; u8 acquired = FALSE; ACPI_FUNCTION_TRACE(ev_acquire_global_lock); /* * Only one thread can acquire the GL at a time, the global_lock_mutex * enforces this. This interface releases the interpreter if we must wait. */ status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex->mutex. os_mutex, timeout); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* * Update the global lock handle and check for wraparound. The handle is * only used for the external global lock interfaces, but it is updated * here to properly handle the case where a single thread may acquire the * lock via both the AML and the acpi_acquire_global_lock interfaces. The * handle is therefore updated on the first acquire from a given thread * regardless of where the acquisition request originated. */ acpi_gbl_global_lock_handle++; if (acpi_gbl_global_lock_handle == 0) { acpi_gbl_global_lock_handle = 1; } /* * Make sure that a global lock actually exists. If not, just * treat the lock as a standard mutex. */ if (!acpi_gbl_global_lock_present) { acpi_gbl_global_lock_acquired = TRUE; return_ACPI_STATUS(AE_OK); } flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock); do { /* Attempt to acquire the actual hardware lock */ ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); if (acquired) { acpi_gbl_global_lock_acquired = TRUE; ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Acquired hardware Global Lock\n")); break; } /* * Did not get the lock. The pending bit was set above, and * we must now wait until we receive the global lock * released interrupt. */ acpi_gbl_global_lock_pending = TRUE; acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags); ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n")); /* * Wait for handshake with the global lock interrupt handler. * This interface releases the interpreter if we must wait. */ status = acpi_ex_system_wait_semaphore (acpi_gbl_global_lock_semaphore, ACPI_WAIT_FOREVER); flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock); } while (ACPI_SUCCESS(status)); acpi_gbl_global_lock_pending = FALSE; acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags); return_ACPI_STATUS(status); }
acpi_status acpi_ev_acquire_global_lock(u16 timeout) { acpi_status status = AE_OK; u8 acquired = FALSE; ACPI_FUNCTION_TRACE(ev_acquire_global_lock); /* * Only one thread can acquire the GL at a time, the global_lock_mutex * enforces this. This interface releases the interpreter if we must wait. */ status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, 0); if (status == AE_TIME) { if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) { acpi_ev_global_lock_acquired++; return AE_OK; } } if (ACPI_FAILURE(status)) { status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout); } if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } acpi_ev_global_lock_thread_id = acpi_os_get_thread_id(); acpi_ev_global_lock_acquired++; /* * Make sure that a global lock actually exists. If not, just treat * the lock as a standard mutex. */ if (!acpi_gbl_global_lock_present) { acpi_gbl_global_lock_acquired = TRUE; return_ACPI_STATUS(AE_OK); } /* Attempt to acquire the actual hardware lock */ ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired); if (acquired) { /* We got the lock */ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Acquired hardware Global Lock\n")); acpi_gbl_global_lock_acquired = TRUE; return_ACPI_STATUS(AE_OK); } /* * Did not get the lock. The pending bit was set above, and we must now * wait until we get the global lock released interrupt. */ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n")); /* * Wait for handshake with the global lock interrupt handler. * This interface releases the interpreter if we must wait. */ status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, ACPI_WAIT_FOREVER); return_ACPI_STATUS(status); }