| 631 | } |
| 632 | |
| 633 | static inline void |
| 634 | umtxq_remove_queue(struct umtx_q *uq, int q) |
| 635 | { |
| 636 | struct umtxq_chain *uc; |
| 637 | struct umtxq_queue *uh; |
| 638 | |
| 639 | uc = umtxq_getchain(&uq->uq_key); |
| 640 | UMTXQ_LOCKED_ASSERT(uc); |
| 641 | if (uq->uq_flags & UQF_UMTXQ) { |
| 642 | uh = uq->uq_cur_queue; |
| 643 | TAILQ_REMOVE(&uh->head, uq, uq_link); |
| 644 | uh->length--; |
| 645 | uq->uq_flags &= ~UQF_UMTXQ; |
| 646 | if (TAILQ_EMPTY(&uh->head)) { |
| 647 | KASSERT(uh->length == 0, |
| 648 | ("inconsistent umtxq_queue length")); |
| 649 | #ifdef UMTX_PROFILING |
| 650 | uc->length--; |
| 651 | #endif |
| 652 | LIST_REMOVE(uh, link); |
| 653 | } else { |
| 654 | uh = LIST_FIRST(&uc->uc_spare_queue); |
| 655 | KASSERT(uh != NULL, ("uc_spare_queue is empty")); |
| 656 | LIST_REMOVE(uh, link); |
| 657 | } |
| 658 | uq->uq_spare_queue = uh; |
| 659 | uq->uq_cur_queue = NULL; |
| 660 | } |
| 661 | } |
| 662 | |
| 663 | /* |
| 664 | * Check if there are multiple waiters |
no test coverage detected