| 564 | } |
| 565 | |
| 566 | int ProgramManager::wait(int *retval) |
| 567 | { |
| 568 | PCB *child; |
| 569 | ListItem *item; |
| 570 | bool interrupt, flag; |
| 571 | |
| 572 | while (true) |
| 573 | { |
| 574 | interrupt = interruptManager.getInterruptStatus(); |
| 575 | interruptManager.disableInterrupt(); |
| 576 | |
| 577 | item = this->allPrograms.head.next; |
| 578 | |
| 579 | // 查找子进程 |
| 580 | flag = true; |
| 581 | while (item) |
| 582 | { |
| 583 | child = ListItem2PCB(item, tagInAllList); |
| 584 | if (child->parentPid == this->running->pid) |
| 585 | { |
| 586 | flag = false; |
| 587 | if (child->status == ProgramStatus::DEAD) |
| 588 | { |
| 589 | break; |
| 590 | } |
| 591 | } |
| 592 | item = item->next; |
| 593 | } |
| 594 | |
| 595 | if (item) // 找到一个可返回的子进程 |
| 596 | { |
| 597 | if (retval) |
| 598 | { |
| 599 | *retval = child->retValue; |
| 600 | } |
| 601 | |
| 602 | int pid = child->pid; |
| 603 | releasePCB(child); |
| 604 | interruptManager.setInterruptStatus(interrupt); |
| 605 | return pid; |
| 606 | } |
| 607 | else |
| 608 | { |
| 609 | if (flag) // 子进程已经返回 |
| 610 | { |
| 611 | |
| 612 | interruptManager.setInterruptStatus(interrupt); |
| 613 | return -1; |
| 614 | } |
| 615 | else // 存在子进程,但子进程的状态不是DEAD |
| 616 | { |
| 617 | interruptManager.setInterruptStatus(interrupt); |
| 618 | schedule(); |
| 619 | } |
| 620 | } |
| 621 | } |
| 622 | } |
no test coverage detected