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