(self, f: F)
| 951 | let member_data = self.get_member_data(); |
| 952 | loop { |
| 953 | // This is only used to select candidate seats; any seat may in fact |
| 954 | // be claimed by a concurrent call to `try_enroll` or |
| 955 | // `try_enroll_many`. |
| 956 | let claimed_bitmask = self.claimed_bitmask.load(Ordering::Relaxed); |
| 957 | if claimed_bitmask == u32::MAX { |
| 958 | return Vec::new(); |
| 959 | } |
| 960 | |
| 961 | // Build a mask of up to `n` free seats by walking the complement. |
| 962 | let mut enrolled_bitmask = 0; |
| 963 | let mut available_bitmask = !claimed_bitmask; |
| 964 | for _ in 0..n { |
| 965 | if available_bitmask == 0 { |
| 966 | break; |
| 967 | } |
| 968 | // Isolate the lowest available bit and add it to the enrollment |
| 969 | // bits |
| 970 | enrolled_bitmask |= |
| 971 | available_bitmask & available_bitmask.wrapping_neg(); |
| 972 | // Remove that bit from the available bits |
| 973 | available_bitmask &= available_bitmask - 1; |
| 974 | } |
| 975 | |
| 976 | // This RMW tries to atomically claim the selected seats all at |
| 977 | // once. Doing this in a single step keeps the batch claim atomic |
| 978 | // with respect to other concurrent `try_enroll_many` calls, and can |
| 979 | // prevent livelocks. |
| 980 | // |
| 981 | // We use `Acquire` ordering on success to synchronize with the |
| 982 | // `Release` RMW any previous owner would make during resignation. |
| 983 | // If the CAS fails we lost a race and retry; since we claimed |
| 984 | // nothing, the failure ordering can be `Relaxed`. |
| 985 | if self |
| 986 | .claimed_bitmask |
| 987 | .compare_exchange( |
| 988 | claimed_bitmask, |
| 989 | claimed_bitmask | enrolled_bitmask, |
| 990 | Ordering::Acquire, |
| 991 | Ordering::Relaxed, |
| 992 | ) |
| 993 | .is_ok() |
| 994 | { |
| 995 | return (0..32) |
| 996 | .filter(|&i| enrolled_bitmask & (1 << i) != 0) |
| 997 | .map(|seat_number| Membership { |
| 998 | thread_pool: self, |
| 999 | member_index: seat_number as usize, |
| 1000 | member_data, |
| 1001 | }) |
| 1002 | .collect(); |
| 1003 | } |
| 1004 | } |
| 1005 | } |
| 1006 | |
| 1007 | /// Blocks workers from resigning from the pool. |
| 1008 | /// |
| 1009 | /// Each call to this function must be paired with exactly one following |
| 1010 | /// call to `unfreeze_membership`. |
no test coverage detected