Debugger multithreading enhancements.

Implemented enhancements to the multithreading support within the debugger to enable better multithreading evaluation of the subsystem.
This commit is contained in:
rmoore1 2006-12-08 22:50:46 +00:00
parent 851c390750
commit b2f39803f4
5 changed files with 196 additions and 41 deletions

View File

@ -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 */

View File

@ -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
/*******************************************************************************
*

View File

@ -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__ */

View File

@ -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;

View File

@ -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);
}