* A CPU is entering for the first time or a thread is exiting. */
| 1659 | * A CPU is entering for the first time or a thread is exiting. |
| 1660 | */ |
| 1661 | void |
| 1662 | sched_throw(struct thread *td) |
| 1663 | { |
| 1664 | /* |
| 1665 | * Correct spinlock nesting. The idle thread context that we are |
| 1666 | * borrowing was created so that it would start out with a single |
| 1667 | * spin lock (sched_lock) held in fork_trampoline(). Since we've |
| 1668 | * explicitly acquired locks in this function, the nesting count |
| 1669 | * is now 2 rather than 1. Since we are nested, calling |
| 1670 | * spinlock_exit() will simply adjust the counts without allowing |
| 1671 | * spin lock using code to interrupt us. |
| 1672 | */ |
| 1673 | if (td == NULL) { |
| 1674 | mtx_lock_spin(&sched_lock); |
| 1675 | spinlock_exit(); |
| 1676 | PCPU_SET(switchtime, cpu_ticks()); |
| 1677 | PCPU_SET(switchticks, ticks); |
| 1678 | } else { |
| 1679 | lock_profile_release_lock(&sched_lock.lock_object); |
| 1680 | MPASS(td->td_lock == &sched_lock); |
| 1681 | td->td_lastcpu = td->td_oncpu; |
| 1682 | td->td_oncpu = NOCPU; |
| 1683 | } |
| 1684 | mtx_assert(&sched_lock, MA_OWNED); |
| 1685 | KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid count")); |
| 1686 | cpu_throw(td, choosethread()); /* doesn't return */ |
| 1687 | } |
| 1688 | |
| 1689 | void |
| 1690 | sched_fork_exit(struct thread *td) |
nothing calls this directly
no test coverage detected