| 656 | */ |
| 657 | |
| 658 | static struct proc * |
| 659 | swapper_selector(bool wkilled_only) |
| 660 | { |
| 661 | struct proc *p, *res; |
| 662 | struct thread *td; |
| 663 | int ppri, pri, slptime, swtime; |
| 664 | |
| 665 | sx_assert(&allproc_lock, SA_SLOCKED); |
| 666 | if (swapped_cnt == 0) |
| 667 | return (NULL); |
| 668 | res = NULL; |
| 669 | ppri = INT_MIN; |
| 670 | FOREACH_PROC_IN_SYSTEM(p) { |
| 671 | PROC_LOCK(p); |
| 672 | if (p->p_state == PRS_NEW || (p->p_flag & (P_SWAPPINGOUT | |
| 673 | P_SWAPPINGIN | P_INMEM)) != 0) { |
| 674 | PROC_UNLOCK(p); |
| 675 | continue; |
| 676 | } |
| 677 | if (p->p_state == PRS_NORMAL && (p->p_flag & P_WKILLED) != 0) { |
| 678 | /* |
| 679 | * A swapped-out process might have mapped a |
| 680 | * large portion of the system's pages as |
| 681 | * anonymous memory. There is no other way to |
| 682 | * release the memory other than to kill the |
| 683 | * process, for which we need to swap it in. |
| 684 | */ |
| 685 | return (p); |
| 686 | } |
| 687 | if (wkilled_only) { |
| 688 | PROC_UNLOCK(p); |
| 689 | continue; |
| 690 | } |
| 691 | swtime = (ticks - p->p_swtick) / hz; |
| 692 | FOREACH_THREAD_IN_PROC(p, td) { |
| 693 | /* |
| 694 | * An otherwise runnable thread of a process |
| 695 | * swapped out has only the TDI_SWAPPED bit set. |
| 696 | */ |
| 697 | thread_lock(td); |
| 698 | if (td->td_inhibitors == TDI_SWAPPED) { |
| 699 | slptime = (ticks - td->td_slptick) / hz; |
| 700 | pri = swtime + slptime; |
| 701 | if ((td->td_flags & TDF_SWAPINREQ) == 0) |
| 702 | pri -= p->p_nice * 8; |
| 703 | /* |
| 704 | * if this thread is higher priority |
| 705 | * and there is enough space, then select |
| 706 | * this process instead of the previous |
| 707 | * selection. |
| 708 | */ |
| 709 | if (pri > ppri) { |
| 710 | res = p; |
| 711 | ppri = pri; |
| 712 | } |
| 713 | } |
| 714 | thread_unlock(td); |
| 715 | } |