summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorRobert Moore <Robert.Moore@intel.com>2013-08-22 12:55:20 -0700
committerRobert Moore <Robert.Moore@intel.com>2013-08-22 12:55:20 -0700
commitb0cf3e5a0949bbe13ea93cf5ea83c7f4ee966f3a (patch)
treee917dc18ceae2154779f57741af5642a9e58e09a /source
parentd36dbb46cab69f14a0f44ad6d40fe79845875386 (diff)
downloadacpica-b0cf3e5a0949bbe13ea93cf5ea83c7f4ee966f3a.tar.gz
SCI handlers: Optimize installation by only locking SCI list once.
The code was locking the list twice. Allocate the new SCI handler object up front to eliminate the second lock, and free the object on any error.
Diffstat (limited to 'source')
-rw-r--r--source/components/events/evxface.c52
1 files changed, 29 insertions, 23 deletions
diff --git a/source/components/events/evxface.c b/source/components/events/evxface.c
index d43fe8d60..c95667bf3 100644
--- a/source/components/events/evxface.c
+++ b/source/components/events/evxface.c
@@ -523,6 +523,7 @@ AcpiInstallSciHandler (
ACPI_SCI_HANDLER Address,
void *Context)
{
+ ACPI_SCI_HANDLER_INFO *NewSciHandler;
ACPI_SCI_HANDLER_INFO *SciHandler;
ACPI_CPU_FLAGS Flags;
ACPI_STATUS Status;
@@ -536,52 +537,57 @@ AcpiInstallSciHandler (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
+ /* Allocate and init a handler object */
+
+ NewSciHandler = ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO));
+ if (!NewSciHandler)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ NewSciHandler->Address = Address;
+ NewSciHandler->Context = Context;
+
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
if (ACPI_FAILURE (Status))
{
- return_ACPI_STATUS (Status);
+ goto Exit;
}
- /* Ensure handler does not already exist */
+ /* Lock list during installation */
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
SciHandler = AcpiGbl_SciHandlerList;
+
+ /* Ensure handler does not already exist */
+
while (SciHandler)
{
if (Address == SciHandler->Address)
{
Status = AE_ALREADY_EXISTS;
- goto UnlockAndExit2;
+ goto UnlockAndExit;
}
- SciHandler = SciHandler->Next;
- }
- AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
- /* Allocate and init handler object */
-
- SciHandler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_SCI_HANDLER_INFO));
- if (!SciHandler)
- {
- Status = AE_NO_MEMORY;
- goto UnlockAndExit;
+ SciHandler = SciHandler->Next;
}
- SciHandler->Address = Address;
- SciHandler->Context = Context;
-
- /* Install the new handler into the global list with lock */
+ /* Install the new handler into the global list (at head) */
- Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+ NewSciHandler->Next = AcpiGbl_SciHandlerList;
+ AcpiGbl_SciHandlerList = NewSciHandler;
- SciHandler->Next = AcpiGbl_SciHandlerList;
- AcpiGbl_SciHandlerList = SciHandler;
-UnlockAndExit2:
+UnlockAndExit:
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
-
-UnlockAndExit:
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+
+Exit:
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_FREE (NewSciHandler);
+ }
return_ACPI_STATUS (Status);
}