about summary refs log tree commit diff
path: root/library/std/src/sys/sgx/abi/tls.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src/sys/sgx/abi/tls.rs')
-rw-r--r--library/std/src/sys/sgx/abi/tls.rs116
1 files changed, 2 insertions, 114 deletions
diff --git a/library/std/src/sys/sgx/abi/tls.rs b/library/std/src/sys/sgx/abi/tls.rs
index 2b0485c4f03..0d8952b2f27 100644
--- a/library/std/src/sys/sgx/abi/tls.rs
+++ b/library/std/src/sys/sgx/abi/tls.rs
@@ -1,3 +1,5 @@
+mod sync_bitset;
+
 use self::sync_bitset::*;
 use crate::cell::Cell;
 use crate::mem;
@@ -125,117 +127,3 @@ impl Tls {
         TLS_KEY_IN_USE.clear(key.to_index());
     }
 }
-
-mod sync_bitset {
-    use super::{TLS_KEYS_BITSET_SIZE, USIZE_BITS};
-    use crate::iter::{Enumerate, Peekable};
-    use crate::slice::Iter;
-    use crate::sync::atomic::{AtomicUsize, Ordering};
-
-    /// A bitset that can be used synchronously.
-    pub(super) struct SyncBitset([AtomicUsize; TLS_KEYS_BITSET_SIZE]);
-
-    pub(super) const SYNC_BITSET_INIT: SyncBitset =
-        SyncBitset([AtomicUsize::new(0), AtomicUsize::new(0)]);
-
-    impl SyncBitset {
-        pub fn get(&self, index: usize) -> bool {
-            let (hi, lo) = Self::split(index);
-            (self.0[hi].load(Ordering::Relaxed) & lo) != 0
-        }
-
-        /// Not atomic.
-        pub fn iter(&self) -> SyncBitsetIter<'_> {
-            SyncBitsetIter { iter: self.0.iter().enumerate().peekable(), elem_idx: 0 }
-        }
-
-        pub fn clear(&self, index: usize) {
-            let (hi, lo) = Self::split(index);
-            self.0[hi].fetch_and(!lo, Ordering::Relaxed);
-        }
-
-        /// Sets any unset bit. Not atomic. Returns `None` if all bits were
-        /// observed to be set.
-        pub fn set(&self) -> Option<usize> {
-            'elems: for (idx, elem) in self.0.iter().enumerate() {
-                let mut current = elem.load(Ordering::Relaxed);
-                loop {
-                    if 0 == !current {
-                        continue 'elems;
-                    }
-                    let trailing_ones = (!current).trailing_zeros() as usize;
-                    match elem.compare_exchange(
-                        current,
-                        current | (1 << trailing_ones),
-                        Ordering::AcqRel,
-                        Ordering::Relaxed,
-                    ) {
-                        Ok(_) => return Some(idx * USIZE_BITS + trailing_ones),
-                        Err(previous) => current = previous,
-                    }
-                }
-            }
-            None
-        }
-
-        fn split(index: usize) -> (usize, usize) {
-            (index / USIZE_BITS, 1 << (index % USIZE_BITS))
-        }
-    }
-
-    pub(super) struct SyncBitsetIter<'a> {
-        iter: Peekable<Enumerate<Iter<'a, AtomicUsize>>>,
-        elem_idx: usize,
-    }
-
-    impl<'a> Iterator for SyncBitsetIter<'a> {
-        type Item = usize;
-
-        fn next(&mut self) -> Option<usize> {
-            self.iter.peek().cloned().and_then(|(idx, elem)| {
-                let elem = elem.load(Ordering::Relaxed);
-                let low_mask = (1 << self.elem_idx) - 1;
-                let next = elem & !low_mask;
-                let next_idx = next.trailing_zeros() as usize;
-                self.elem_idx = next_idx + 1;
-                if self.elem_idx >= 64 {
-                    self.elem_idx = 0;
-                    self.iter.next();
-                }
-                match next_idx {
-                    64 => self.next(),
-                    _ => Some(idx * USIZE_BITS + next_idx),
-                }
-            })
-        }
-    }
-
-    #[cfg(test)]
-    mod tests {
-        use super::*;
-
-        fn test_data(bitset: [usize; 2], bit_indices: &[usize]) {
-            let set = SyncBitset([AtomicUsize::new(bitset[0]), AtomicUsize::new(bitset[1])]);
-            assert_eq!(set.iter().collect::<Vec<_>>(), bit_indices);
-            for &i in bit_indices {
-                assert!(set.get(i));
-            }
-        }
-
-        #[test]
-        fn iter() {
-            test_data([0b0110_1001, 0], &[0, 3, 5, 6]);
-            test_data([0x8000_0000_0000_0000, 0x8000_0000_0000_0001], &[63, 64, 127]);
-            test_data([0, 0], &[]);
-        }
-
-        #[test]
-        fn set_get_clear() {
-            let set = SYNC_BITSET_INIT;
-            let key = set.set().unwrap();
-            assert!(set.get(key));
-            set.clear(key);
-            assert!(!set.get(key));
-        }
-    }
-}