From 4ba03be97e6cc7e790bbc9bfc18caaa228c8a262 Mon Sep 17 00:00:00 2001 From: Botahamec Date: Fri, 28 Feb 2025 16:09:11 -0500 Subject: Scoped lock API --- src/collection/utils.rs | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'src/collection/utils.rs') diff --git a/src/collection/utils.rs b/src/collection/utils.rs index d6d50f4..1d96e5c 100644 --- a/src/collection/utils.rs +++ b/src/collection/utils.rs @@ -1,7 +1,35 @@ use std::cell::Cell; use crate::handle_unwind::handle_unwind; -use crate::lockable::RawLock; +use crate::lockable::{Lockable, RawLock}; + +#[must_use] +pub fn get_locks(data: &L) -> Vec<&dyn RawLock> { + let mut locks = Vec::new(); + data.get_ptrs(&mut locks); + locks.sort_by_key(|lock| &raw const **lock); + locks +} + +#[must_use] +pub fn get_locks_unsorted(data: &L) -> Vec<&dyn RawLock> { + let mut locks = Vec::new(); + data.get_ptrs(&mut locks); + locks +} + +/// returns `true` if the sorted list contains a duplicate +#[must_use] +pub fn ordered_contains_duplicates(l: &[&dyn RawLock]) -> bool { + if l.is_empty() { + // Return early to prevent panic in the below call to `windows` + return false; + } + + l.windows(2) + // NOTE: addr_eq is necessary because eq would also compare the v-table pointers + .any(|window| std::ptr::addr_eq(window[0], window[1])) +} /// Lock a set of locks in the given order. It's UB to call this without a `ThreadKey` pub unsafe fn ordered_lock(locks: &[&dyn RawLock]) { @@ -115,3 +143,13 @@ pub unsafe fn attempt_to_recover_reads_from_panic(locked: &[&dyn RawLock]) { || locked.iter().for_each(|l| l.poison()), ) } + +#[cfg(test)] +mod tests { + use crate::collection::utils::ordered_contains_duplicates; + + #[test] + fn empty_array_does_not_contain_duplicates() { + assert!(!ordered_contains_duplicates(&[])) + } +} -- cgit v1.2.3