* vm_page_sunbusy: * * Shared unbusy a page. */
| 973 | * Shared unbusy a page. |
| 974 | */ |
| 975 | void |
| 976 | vm_page_sunbusy(vm_page_t m) |
| 977 | { |
| 978 | u_int x; |
| 979 | |
| 980 | vm_page_assert_sbusied(m); |
| 981 | |
| 982 | x = vm_page_busy_fetch(m); |
| 983 | for (;;) { |
| 984 | KASSERT(x != VPB_FREED, |
| 985 | ("vm_page_sunbusy: Unlocking freed page.")); |
| 986 | if (VPB_SHARERS(x) > 1) { |
| 987 | if (atomic_fcmpset_int(&m->busy_lock, &x, |
| 988 | x - VPB_ONE_SHARER)) |
| 989 | break; |
| 990 | continue; |
| 991 | } |
| 992 | KASSERT((x & ~VPB_BIT_WAITERS) == VPB_SHARERS_WORD(1), |
| 993 | ("vm_page_sunbusy: invalid lock state")); |
| 994 | if (!atomic_fcmpset_rel_int(&m->busy_lock, &x, VPB_UNBUSIED)) |
| 995 | continue; |
| 996 | if ((x & VPB_BIT_WAITERS) == 0) |
| 997 | break; |
| 998 | wakeup(m); |
| 999 | break; |
| 1000 | } |
| 1001 | } |
| 1002 | |
| 1003 | /* |
| 1004 | * vm_page_busy_sleep: |
no test coverage detected