1/******************************************************************************
2 *
3 * Module Name: dsmethod - Parser/Interpreter interface - control method parsing
4 * $Revision: 94 $
5 *
6 *****************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp.
--- 164 unchanged lines hidden (view full) ---
177 ObjDesc = AcpiNsGetAttachedObject (Node);
178 if (!ObjDesc)
179 {
180 return_ACPI_STATUS (AE_NULL_OBJECT);
181 }
182
183 /* Create a mutex for the method if there is a concurrency limit */
184
185 if ((ObjDesc->Method.Concurrency != ACPI_INFINITE_CONCURRENCY) &&
186 (!ObjDesc->Method.Semaphore))
187 {
188 Status = AcpiOsCreateSemaphore (ObjDesc->Method.Concurrency,
189 ObjDesc->Method.Concurrency,
190 &ObjDesc->Method.Semaphore);
191 if (ACPI_FAILURE (Status))
192 {
193 return_ACPI_STATUS (Status);
--- 190 unchanged lines hidden (view full) ---
384
385 Status = AcpiDsBeginMethodExecution (MethodNode, ObjDesc,
386 ThisWalkState->MethodNode);
387 if (ACPI_FAILURE (Status))
388 {
389 return_ACPI_STATUS (Status);
390 }
391
392 if (!(ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY))
393 {
394 /* 1) Parse: Create a new walk state for the preempting walk */
395
396 NextWalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwningId,
397 Op, ObjDesc, NULL);
398 if (!NextWalkState)
399 {
400 return_ACPI_STATUS (AE_NO_MEMORY);
401 }
402
403
404 /* Create and init a Root Node */
405
406 Op = AcpiPsCreateScopeOp ();
407 if (!Op)
408 {
409 Status = AE_NO_MEMORY;
410 goto Cleanup;
411 }
412
413 Status = AcpiDsInitAmlWalk (NextWalkState, Op, MethodNode,
414 ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength,
415 NULL, NULL, 1);
416 if (ACPI_FAILURE (Status))
417 {
418 AcpiDsDeleteWalkState (NextWalkState);
419 goto Cleanup;
420 }
421
422 /* Begin AML parse */
423
424 Status = AcpiPsParseAml (NextWalkState);
425 AcpiPsDeleteParseTree (Op);
426 }
427
428 /* 2) Execute: Create a new state for the preempting walk */
429
430 NextWalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwningId,
431 NULL, ObjDesc, Thread);
432 if (!NextWalkState)
433 {
434 Status = AE_NO_MEMORY;
435 goto Cleanup;
436 }
437 /*
438 * The resolved arguments were put on the previous walk state's operand
439 * stack. Operands on the previous walk state stack always
440 * start at index 0.
441 * Null terminate the list of arguments
442 */
443 ThisWalkState->Operands [ThisWalkState->NumOperands] = NULL;
444
--- 17 unchanged lines hidden (view full) ---
462
463 /* Clear the operand stack */
464
465 ThisWalkState->NumOperands = 0;
466
467 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
468 "Starting nested execution, newstate=%p\n", NextWalkState));
469
470 if (ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY)
471 {
472 Status = ObjDesc->Method.Implementation (NextWalkState);
473 return_ACPI_STATUS (Status);
474 }
475
476 return_ACPI_STATUS (AE_OK);
477
478
479 /* On error, we must delete the new walk state */
480
481Cleanup:
482 if (NextWalkState->MethodDesc)
483 {
484 /* Decrement the thread count on the method parse tree */
485
486 NextWalkState->MethodDesc->Method.ThreadCount--;
487 }
488 (void) AcpiDsTerminateControlMethod (NextWalkState);
489 AcpiDsDeleteWalkState (NextWalkState);
490 return_ACPI_STATUS (Status);
491}
492
493
494/*******************************************************************************
495 *
496 * FUNCTION: AcpiDsRestartControlMethod
497 *
498 * PARAMETERS: WalkState - State of the method when it was preempted
--- 114 unchanged lines hidden (view full) ---
613 {
614 ACPI_REPORT_ERROR (("Could not signal method semaphore\n"));
615 Status = AE_OK;
616
617 /* Ignore error and continue cleanup */
618 }
619 }
620
621 if (WalkState->MethodDesc->Method.ThreadCount)
622 {
623 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
624 "*** Not deleting method namespace, there are still %d threads\n",
625 WalkState->MethodDesc->Method.ThreadCount));
626 }
627
628 if (!WalkState->MethodDesc->Method.ThreadCount)
629 {
630 /*
631 * Support to dynamically change a method from NotSerialized to
632 * Serialized if it appears that the method is written foolishly and
633 * does not support multiple thread execution. The best example of this
634 * is if such a method creates namespace objects and blocks. A second
635 * thread will fail with an AE_ALREADY_EXISTS exception
636 *
637 * This code is here because we must wait until the last thread exits
638 * before creating the synchronization semaphore.
639 */
640 if ((WalkState->MethodDesc->Method.Concurrency == 1) &&
641 (!WalkState->MethodDesc->Method.Semaphore))
642 {
643 Status = AcpiOsCreateSemaphore (1,
644 1,
645 &WalkState->MethodDesc->Method.Semaphore);
646 }
647
648 /*
649 * There are no more threads executing this method. Perform
650 * additional cleanup.
651 *
652 * The method Node is stored in the walk state
653 */
654 MethodNode = WalkState->MethodNode;
655
656 /*
--- 31 unchanged lines hidden ---
2 *
3 * Module Name: dsmethod - Parser/Interpreter interface - control method parsing
4 * $Revision: 94 $
5 *
6 *****************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp.
--- 164 unchanged lines hidden (view full) ---
177 ObjDesc = AcpiNsGetAttachedObject (Node);
178 if (!ObjDesc)
179 {
180 return_ACPI_STATUS (AE_NULL_OBJECT);
181 }
182
183 /* Create a mutex for the method if there is a concurrency limit */
184
185 if ((ObjDesc->Method.Concurrency != ACPI_INFINITE_CONCURRENCY) &&
186 (!ObjDesc->Method.Semaphore))
187 {
188 Status = AcpiOsCreateSemaphore (ObjDesc->Method.Concurrency,
189 ObjDesc->Method.Concurrency,
190 &ObjDesc->Method.Semaphore);
191 if (ACPI_FAILURE (Status))
192 {
193 return_ACPI_STATUS (Status);
--- 190 unchanged lines hidden (view full) ---
384
385 Status = AcpiDsBeginMethodExecution (MethodNode, ObjDesc,
386 ThisWalkState->MethodNode);
387 if (ACPI_FAILURE (Status))
388 {
389 return_ACPI_STATUS (Status);
390 }
391
392 if (!(ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY))
393 {
394 /* 1) Parse: Create a new walk state for the preempting walk */
395
396 NextWalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwningId,
397 Op, ObjDesc, NULL);
398 if (!NextWalkState)
399 {
400 return_ACPI_STATUS (AE_NO_MEMORY);
401 }
402
403
404 /* Create and init a Root Node */
405
406 Op = AcpiPsCreateScopeOp ();
407 if (!Op)
408 {
409 Status = AE_NO_MEMORY;
410 goto Cleanup;
411 }
412
413 Status = AcpiDsInitAmlWalk (NextWalkState, Op, MethodNode,
414 ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength,
415 NULL, NULL, 1);
416 if (ACPI_FAILURE (Status))
417 {
418 AcpiDsDeleteWalkState (NextWalkState);
419 goto Cleanup;
420 }
421
422 /* Begin AML parse */
423
424 Status = AcpiPsParseAml (NextWalkState);
425 AcpiPsDeleteParseTree (Op);
426 }
427
428 /* 2) Execute: Create a new state for the preempting walk */
429
430 NextWalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwningId,
431 NULL, ObjDesc, Thread);
432 if (!NextWalkState)
433 {
434 Status = AE_NO_MEMORY;
435 goto Cleanup;
436 }
437 /*
438 * The resolved arguments were put on the previous walk state's operand
439 * stack. Operands on the previous walk state stack always
440 * start at index 0.
441 * Null terminate the list of arguments
442 */
443 ThisWalkState->Operands [ThisWalkState->NumOperands] = NULL;
444
--- 17 unchanged lines hidden (view full) ---
462
463 /* Clear the operand stack */
464
465 ThisWalkState->NumOperands = 0;
466
467 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
468 "Starting nested execution, newstate=%p\n", NextWalkState));
469
470 if (ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY)
471 {
472 Status = ObjDesc->Method.Implementation (NextWalkState);
473 return_ACPI_STATUS (Status);
474 }
475
476 return_ACPI_STATUS (AE_OK);
477
478
479 /* On error, we must delete the new walk state */
480
481Cleanup:
482 if (NextWalkState->MethodDesc)
483 {
484 /* Decrement the thread count on the method parse tree */
485
486 NextWalkState->MethodDesc->Method.ThreadCount--;
487 }
488 (void) AcpiDsTerminateControlMethod (NextWalkState);
489 AcpiDsDeleteWalkState (NextWalkState);
490 return_ACPI_STATUS (Status);
491}
492
493
494/*******************************************************************************
495 *
496 * FUNCTION: AcpiDsRestartControlMethod
497 *
498 * PARAMETERS: WalkState - State of the method when it was preempted
--- 114 unchanged lines hidden (view full) ---
613 {
614 ACPI_REPORT_ERROR (("Could not signal method semaphore\n"));
615 Status = AE_OK;
616
617 /* Ignore error and continue cleanup */
618 }
619 }
620
621 if (WalkState->MethodDesc->Method.ThreadCount)
622 {
623 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
624 "*** Not deleting method namespace, there are still %d threads\n",
625 WalkState->MethodDesc->Method.ThreadCount));
626 }
627
628 if (!WalkState->MethodDesc->Method.ThreadCount)
629 {
630 /*
631 * Support to dynamically change a method from NotSerialized to
632 * Serialized if it appears that the method is written foolishly and
633 * does not support multiple thread execution. The best example of this
634 * is if such a method creates namespace objects and blocks. A second
635 * thread will fail with an AE_ALREADY_EXISTS exception
636 *
637 * This code is here because we must wait until the last thread exits
638 * before creating the synchronization semaphore.
639 */
640 if ((WalkState->MethodDesc->Method.Concurrency == 1) &&
641 (!WalkState->MethodDesc->Method.Semaphore))
642 {
643 Status = AcpiOsCreateSemaphore (1,
644 1,
645 &WalkState->MethodDesc->Method.Semaphore);
646 }
647
648 /*
649 * There are no more threads executing this method. Perform
650 * additional cleanup.
651 *
652 * The method Node is stored in the walk state
653 */
654 MethodNode = WalkState->MethodNode;
655
656 /*
--- 31 unchanged lines hidden ---