diff --git a/source/components/debugger/dbexec.c b/source/components/debugger/dbexec.c index 4547f0e5b..4a9a0f621 100644 --- a/source/components/debugger/dbexec.c +++ b/source/components/debugger/dbexec.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: dbexec - debugger control method execution - * $Revision: 1.77 $ + * $Revision: 1.78 $ * ******************************************************************************/ @@ -426,6 +426,8 @@ AcpiDbExecute ( return; } + ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); + ACPI_STRCPY (NameString, Name); AcpiUtStrupr (NameString); AcpiGbl_DbMethodInfo.Name = NameString; @@ -509,9 +511,21 @@ AcpiDbMethodThread ( ACPI_STATUS Status; ACPI_DB_METHOD_INFO *Info = Context; UINT32 i; + UINT8 Allow; ACPI_BUFFER ReturnObj; + if (Info->InitArgs) + { + AcpiDbUInt32ToHexString (Info->NumCreated, Info->IndexOfThreadStr); + AcpiDbUInt32ToHexString (AcpiOsGetThreadId (), Info->IdOfThreadStr); + } + + if (Info->Threads && (Info->NumCreated < Info->NumThreads)) + { + Info->Threads[Info->NumCreated++] = AcpiOsGetThreadId(); + } + for (i = 0; i < Info->NumLoops; i++) { Status = AcpiDbExecuteMethod (Info, &ReturnObj); @@ -525,12 +539,12 @@ AcpiDbMethodThread ( } } +#if 0 if ((i % 100) == 0) { - AcpiOsPrintf ("%d executions\n", i); + AcpiOsPrintf ("%d executions, Thread 0x%x\n", i, AcpiOsGetThreadId ()); } -#if 0 if (ReturnObj.Length) { AcpiOsPrintf ("Execution of %s returned object %p Buflen %X\n", @@ -542,11 +556,26 @@ AcpiDbMethodThread ( /* Signal our completion */ - Status = AcpiOsSignalSemaphore (Info->ThreadGate, 1); - if (ACPI_FAILURE (Status)) + Allow = 0; + AcpiOsWaitSemaphore (Info->ThreadCompleteGate, 1, ACPI_WAIT_FOREVER); + Info->NumCompleted++; + + if (Info->NumCompleted == Info->NumCreated) { - AcpiOsPrintf ("Could not signal debugger thread sync semaphore, %s\n", - AcpiFormatException (Status)); + /* Do signal for main thread once only */ + Allow = 1; + } + + AcpiOsSignalSemaphore (Info->ThreadCompleteGate, 1); + + if (Allow) + { + Status = AcpiOsSignalSemaphore (Info->MainThreadGate, 1); + if (ACPI_FAILURE (Status)) + { + AcpiOsPrintf ("Could not signal debugger thread sync semaphore, %s\n", + AcpiFormatException (Status)); + } } } @@ -575,8 +604,9 @@ AcpiDbCreateExecutionThreads ( UINT32 NumThreads; UINT32 NumLoops; UINT32 i; - ACPI_MUTEX ThreadGate; - + UINT32 Size; + ACPI_MUTEX MainThreadGate; + ACPI_MUTEX ThreadCompleteGate; /* Get the arguments */ @@ -590,23 +620,64 @@ AcpiDbCreateExecutionThreads ( return; } - /* Create the synchronization semaphore */ - - Status = AcpiOsCreateSemaphore (1, 0, &ThreadGate); + /* + * Create the semaphore for synchronization of + * the created threads with the main thread. + */ + Status = AcpiOsCreateSemaphore (1, 0, &MainThreadGate); if (ACPI_FAILURE (Status)) { - AcpiOsPrintf ("Could not create semaphore, %s\n", + AcpiOsPrintf ("Could not create semaphore for synchronization with the main thread, %s\n", AcpiFormatException (Status)); return; } + /* + * Create the semaphore for synchronization + * between the created threads. + */ + Status = AcpiOsCreateSemaphore (1, 1, &ThreadCompleteGate); + if (ACPI_FAILURE (Status)) + { + AcpiOsPrintf ("Could not create semaphore for synchronization between the created threads, %s\n", + AcpiFormatException (Status)); + (void) AcpiOsDeleteSemaphore (MainThreadGate); + return; + } + + ACPI_MEMSET (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); + + /* Array to store IDs of threads */ + + AcpiGbl_DbMethodInfo.NumThreads = NumThreads; + Size = 4 * AcpiGbl_DbMethodInfo.NumThreads; + AcpiGbl_DbMethodInfo.Threads = (UINT32 *) AcpiOsAllocate (Size); + if (AcpiGbl_DbMethodInfo.Threads == NULL) + { + AcpiOsPrintf ("No memory for thread IDs array\n"); + (void) AcpiOsDeleteSemaphore (MainThreadGate); + (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); + return; + } + ACPI_MEMSET (AcpiGbl_DbMethodInfo.Threads, 0, Size); + /* Setup the context to be passed to each thread */ AcpiGbl_DbMethodInfo.Name = MethodNameArg; - AcpiGbl_DbMethodInfo.Args = NULL; AcpiGbl_DbMethodInfo.Flags = 0; AcpiGbl_DbMethodInfo.NumLoops = NumLoops; - AcpiGbl_DbMethodInfo.ThreadGate = ThreadGate; + AcpiGbl_DbMethodInfo.MainThreadGate = MainThreadGate; + AcpiGbl_DbMethodInfo.ThreadCompleteGate = ThreadCompleteGate; + + /* Init arguments to be passed to method */ + + AcpiGbl_DbMethodInfo.InitArgs = 1; + AcpiGbl_DbMethodInfo.Args = AcpiGbl_DbMethodInfo.Arguments; + AcpiGbl_DbMethodInfo.Arguments[0] = AcpiGbl_DbMethodInfo.NumThreadsStr; + AcpiGbl_DbMethodInfo.Arguments[1] = AcpiGbl_DbMethodInfo.IdOfThreadStr; + AcpiGbl_DbMethodInfo.Arguments[2] = AcpiGbl_DbMethodInfo.IndexOfThreadStr; + AcpiGbl_DbMethodInfo.Arguments[3] = NULL; + AcpiDbUInt32ToHexString (NumThreads, AcpiGbl_DbMethodInfo.NumThreadsStr); AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); @@ -627,20 +698,19 @@ AcpiDbCreateExecutionThreads ( /* Wait for all threads to complete */ - i = NumThreads; - while (i) /* Brain damage for host OSs that only support wait of 1 unit */ - { - Status = AcpiOsWaitSemaphore (ThreadGate, 1, ACPI_WAIT_FOREVER); - i--; - } - - /* Cleanup and exit */ - - (void) AcpiOsDeleteSemaphore (ThreadGate); + AcpiOsWaitSemaphore (MainThreadGate, 1, ACPI_WAIT_FOREVER); AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); AcpiOsPrintf ("All threads (%X) have completed\n", NumThreads); AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); + + /* Cleanup and exit */ + + (void) AcpiOsDeleteSemaphore (MainThreadGate); + (void) AcpiOsDeleteSemaphore (ThreadCompleteGate); + + AcpiOsFree (AcpiGbl_DbMethodInfo.Threads); + AcpiGbl_DbMethodInfo.Threads = NULL; } #endif /* ACPI_DEBUGGER */ diff --git a/source/components/debugger/dbutils.c b/source/components/debugger/dbutils.c index 5a1b1b017..99de54f56 100644 --- a/source/components/debugger/dbutils.c +++ b/source/components/debugger/dbutils.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: dbutils - AML debugger utilities - * $Revision: 1.81 $ + * $Revision: 1.82 $ * ******************************************************************************/ @@ -138,6 +138,8 @@ AcpiDbDumpBuffer ( UINT32 Address); #endif +static char *Converter = "0123456789ABCDEF"; + /******************************************************************************* * @@ -428,6 +430,47 @@ AcpiDbLocalNsLookup ( } +/******************************************************************************* + * + * FUNCTION: AcpiDbUInt32ToHexString + * + * PARAMETERS: Value - The value to be converted to string + * Buffer - Buffer for result (not less than 11 bytes) + * + * RETURN: None + * + * DESCRIPTION: Convert the unsigned 32-bit value to the hexadecimal image + * + * NOTE: It is the caller's responsibility to ensure that the length of buffer + * is sufficient. + * + ******************************************************************************/ + +void +AcpiDbUInt32ToHexString ( + UINT32 Value, + char *Buffer) +{ + UINT8 i; + + + if (Value == 0) + { + ACPI_STRCPY (Buffer, "0"); + return; + } + + ACPI_STRCPY (Buffer, "0x"); + Buffer[10] = '\0'; + + for (i = 9; i > 1; i--) + { + Buffer[i] = Converter [Value & 0x0F]; + Value = Value >> 4; + } +} + + #ifdef ACPI_OBSOLETE_FUNCTIONS /******************************************************************************* * diff --git a/source/include/acdebug.h b/source/include/acdebug.h index a56bde7cc..3b26dde59 100644 --- a/source/include/acdebug.h +++ b/source/include/acdebug.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acdebug.h - ACPI/AML debugger - * $Revision: 1.81 $ + * $Revision: 1.82 $ * *****************************************************************************/ @@ -423,4 +423,9 @@ ACPI_NAMESPACE_NODE * AcpiDbLocalNsLookup ( char *Name); +void +AcpiDbUInt32ToHexString ( + UINT32 Value, + char *Buffer); + #endif /* __ACDEBUG_H__ */ diff --git a/source/include/aclocal.h b/source/include/aclocal.h index 454fa0971..6e7748304 100644 --- a/source/include/aclocal.h +++ b/source/include/aclocal.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: aclocal.h - Internal data types used across the ACPI subsystem - * $Revision: 1.242 $ + * $Revision: 1.243 $ * *****************************************************************************/ @@ -1092,12 +1092,30 @@ typedef struct acpi_bit_register_info typedef struct acpi_db_method_info { - ACPI_HANDLE ThreadGate; + ACPI_HANDLE MainThreadGate; + ACPI_HANDLE ThreadCompleteGate; + UINT32 *Threads; + UINT32 NumThreads; + UINT32 NumCreated; + UINT32 NumCompleted; + char *Name; - char **Args; UINT32 Flags; UINT32 NumLoops; char Pathname[128]; + char **Args; + + /* + * Arguments to be passed to method for the command + * Threads - + * the Number of threads, ID of current thread and + * Index of current thread inside all them created. + */ + char InitArgs; + char *Arguments[4]; + char NumThreadsStr[11]; + char IdOfThreadStr[11]; + char IndexOfThreadStr[11]; } ACPI_DB_METHOD_INFO; diff --git a/source/tools/acpiexec/aemain.c b/source/tools/acpiexec/aemain.c index e89738576..546272fc1 100644 --- a/source/tools/acpiexec/aemain.c +++ b/source/tools/acpiexec/aemain.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: aemain - Main routine for the AcpiExec utility - * $Revision: 1.108 $ + * $Revision: 1.109 $ * *****************************************************************************/ @@ -163,35 +163,54 @@ usage (void) * * FUNCTION: AcpiDbRunBatchMode * - * PARAMETERS: BatchCommandLine - Comma separated command and arguments + * PARAMETERS: BatchCommandLine - A semicolon separated list of commands + * to be executed. + * Use only commas to separate elements of + * particular command. + * RETURN: Status * - * RETURN: None - * - * DESCRIPTION: Prepare command buffer and pass it to AcpiDbCommandDispatch + * DESCRIPTION: For each command of list separated by ';' prepare the command + * buffer and pass it to AcpiDbCommandDispatch. * *****************************************************************************/ -static void +static ACPI_STATUS AcpiDbRunBatchMode ( void) { + ACPI_STATUS Status; char *Ptr = BatchBuffer; + char *Cmd = Ptr; + UINT8 Run = 0; - /* Convert commas to spaces */ + AcpiGbl_MethodExecuting = FALSE; + AcpiGbl_StepToNextCall = FALSE; while (*Ptr) { if (*Ptr == ',') { + /* Convert commas to spaces */ *Ptr = ' '; } + else if (*Ptr == ';') + { + *Ptr = '\0'; + Run = 1; + } + Ptr++; + + if (Run || (*Ptr == '\0')) + { + (void) AcpiDbCommandDispatch (Cmd, NULL, NULL); + Run = 0; + Cmd = Ptr; + } } - AcpiGbl_MethodExecuting = FALSE; - AcpiGbl_StepToNextCall = FALSE; - - (void) AcpiDbCommandDispatch (BatchBuffer, NULL, NULL); + Status = AcpiTerminate (); + return (Status); }