* Clean up umtx data. */
| 4649 | * Clean up umtx data. |
| 4650 | */ |
| 4651 | static void |
| 4652 | umtx_thread_cleanup(struct thread *td) |
| 4653 | { |
| 4654 | struct umtx_q *uq; |
| 4655 | struct umtx_pi *pi; |
| 4656 | uintptr_t rb_inact; |
| 4657 | bool compat32; |
| 4658 | |
| 4659 | /* |
| 4660 | * Disown pi mutexes. |
| 4661 | */ |
| 4662 | uq = td->td_umtxq; |
| 4663 | if (uq != NULL) { |
| 4664 | if (uq->uq_inherited_pri != PRI_MAX || |
| 4665 | !TAILQ_EMPTY(&uq->uq_pi_contested)) { |
| 4666 | mtx_lock(&umtx_lock); |
| 4667 | uq->uq_inherited_pri = PRI_MAX; |
| 4668 | while ((pi = TAILQ_FIRST(&uq->uq_pi_contested)) != NULL) { |
| 4669 | pi->pi_owner = NULL; |
| 4670 | TAILQ_REMOVE(&uq->uq_pi_contested, pi, pi_link); |
| 4671 | } |
| 4672 | mtx_unlock(&umtx_lock); |
| 4673 | } |
| 4674 | sched_lend_user_prio_cond(td, PRI_MAX); |
| 4675 | } |
| 4676 | |
| 4677 | compat32 = (td->td_pflags2 & TDP2_COMPAT32RB) != 0; |
| 4678 | td->td_pflags2 &= ~TDP2_COMPAT32RB; |
| 4679 | |
| 4680 | if (td->td_rb_inact == 0 && td->td_rb_list == 0 && td->td_rbp_list == 0) |
| 4681 | return; |
| 4682 | |
| 4683 | /* |
| 4684 | * Handle terminated robust mutexes. Must be done after |
| 4685 | * robust pi disown, otherwise unlock could see unowned |
| 4686 | * entries. |
| 4687 | */ |
| 4688 | rb_inact = td->td_rb_inact; |
| 4689 | if (rb_inact != 0) |
| 4690 | (void)umtx_read_uptr(td, rb_inact, &rb_inact, compat32); |
| 4691 | umtx_cleanup_rb_list(td, td->td_rb_list, &rb_inact, "", compat32); |
| 4692 | umtx_cleanup_rb_list(td, td->td_rbp_list, &rb_inact, "priv ", compat32); |
| 4693 | if (rb_inact != 0) |
| 4694 | (void)umtx_handle_rb(td, rb_inact, NULL, true, compat32); |
| 4695 | } |
no test coverage detected