pub fn steal_many(&self, dest: &Worker<T>) -> Steal<T> {
        // Load the front index.
        let mut f = self.inner.front.load(Ordering::Acquire);

        // A SeqCst fence is needed here.
        //
        // If the current thread is already pinned (reentrantly), we must manually issue the
        // fence. Otherwise, the following pinning will issue the fence anyway, so we don't
        // have to.
        if epoch::is_pinned() {
            atomic::fence(Ordering::SeqCst);
        }

        let guard = &epoch::pin();

        // Load the back index.
        let b = self.inner.back.load(Ordering::Acquire);

        // Is the deque empty?
        let len = b.wrapping_sub(f);
        if len <= 0 {
            return Steal::Empty;
        }

        // Reserve capacity for the stolen additional elements.
        let additional = cmp::min((len as usize - 1) / 2, MAX_BATCH);
        dest.reserve(additional);
        let additional = additional as isize;

        // Get the destination buffer and back index.
        let dest_buffer = dest.cached_buffer.get();
        let mut dest_b = dest.inner.back.load(Ordering::Relaxed);

        // Load the buffer and read the value at the front.
        let buffer = self.inner.buffer.load(Ordering::Acquire, guard);
        let value = unsafe { buffer.deref().read(f) };

        match self.flavor {
            // Steal a batch of elements from the front at once.
            Flavor::Fifo => {
                // Copy the additional elements from the source to the destination buffer.
                for i in 0..additional {
                    unsafe {
                        let value = buffer.deref().read(f.wrapping_add(i + 1));
                        dest_buffer.write(dest_b.wrapping_add(i), value);
                    }
                }

                // Try incrementing the front index to steal the batch.
                if self.inner
                    .front
                    .compare_exchange(
                        f,
                        f.wrapping_add(additional + 1),
                        Ordering::SeqCst,
                        Ordering::Relaxed,
                    )
                    .is_err()
                {
                    // We didn't steal this value, forget it.
                    mem::forget(value);
                    return Steal::Retry;
                }

                atomic::fence(Ordering::Release);

                // Success! Update the back index in the destination deque.
                //
                // This ordering could be `Relaxed`, but then thread sanitizer would falsely report
                // data races because it doesn't understand fences.
                dest.inner.back.store(dest_b.wrapping_add(additional), Ordering::Release);

                // Return the first stolen value.
                Steal::Data(value)
            }

            // Steal a batch of elements from the front one by one.
            Flavor::Lifo => {
                // Try incrementing the front index to steal the value.
                if self.inner
                    .front
                    .compare_exchange(f, f.wrapping_add(1), Ordering::SeqCst, Ordering::Relaxed)
                    .is_err()
                {
                    // We didn't steal this value, forget it.
                    mem::forget(value);
                    return Steal::Retry;
                }

                // Move the front index one step forward.
                f = f.wrapping_add(1);

                // Repeat the same procedure for the additional steals.
                for _ in 0..additional {
                    // We've already got the current front index. Now execute the fence to
                    // synchronize with other threads.
                    atomic::fence(Ordering::SeqCst);

                    // Load the back index.
                    let b = self.inner.back.load(Ordering::Acquire);

                    // Is the deque empty?
                    if b.wrapping_sub(f) <= 0 {
                        break;
                    }

                    // Read the value at the front.
                    let value = unsafe { buffer.deref().read(f) };

                    // Try incrementing the front index to steal the value.
                    if self.inner
                        .front
                        .compare_exchange(f, f.wrapping_add(1), Ordering::SeqCst, Ordering::Relaxed)
                        .is_err()
                    {
                        // We didn't steal this value, forget it and break from the loop.
                        mem::forget(value);
                        break;
                    }

                    // Write the stolen value into the destination buffer.
                    unsafe {
                        dest_buffer.write(dest_b, value);
                    }

                    // Move the source front index and the destination back index one step forward.
                    f = f.wrapping_add(1);
                    dest_b = dest_b.wrapping_add(1);

                    atomic::fence(Ordering::Release);

                    // Update the destination back index.
                    //
                    // This ordering could be `Relaxed`, but then thread sanitizer would falsely
                    // report data races because it doesn't understand fences.
                    dest.inner.back.store(dest_b, Ordering::Release);
                }

                // Return the first stolen value.
                Steal::Data(value)
            }
        }
    }
/// Steals elements from the front of the deque.
///
/// If at least one element can be stolen, it will be returned. Additionally, some of the
/// remaining elements will be stolen and pushed into the back of worker `dest` in order to
/// balance the work among deques. There is no hard guarantee on exactly how many elements will
/// be stolen, but it should be around half of the deque.
///
/// # Examples
///
/// ```
/// use crossbeam_deque::{self as deque, Steal};
///
/// let (w1, s1) = deque::fifo();
/// let (w2, s2) = deque::fifo();
///
/// w1.push(1);
/// w1.push(2);
/// w1.push(3);
/// w1.push(4);
///
/// assert_eq!(s1.steal_many(&w2), Steal::Data(1));
/// assert_eq!(s2.steal(), Steal::Data(2));
/// ```
Steals elements from the front of the deque.
If at least one element can be stolen, it will be returned. Additionally, some of the
remaining elements will be stolen and pushed into the back of worker `dest` in order to
balance the work among deques. There is no hard guarantee on exactly how many elements will
be stolen, but it should be around half of the deque.
Steals elements from the front of the deque . If at least one element can be stolen it will be returned . Additionally some of the remaining elements will be stolen and pushed into the back of worker ` dest ` in order to balance the work among deques . There is no hard guarantee on exactly how many elements will be stolen but it should be around half of the deque .
pub fn steal_many(&self, dest: &Worker<T>) -> Steal<T> {
        // Load the front index.
        let mut f = self.inner.front.load(Ordering::Acquire);
        // A SeqCst fence is needed here.
        //
        // If the current thread is already pinned (reentrantly), we must manually issue the
        // fence. Otherwise, the following pinning will issue the fence anyway, so we don't
        // have to.
        if epoch::is_pinned() {
            atomic::fence(Ordering::SeqCst);
        }
        let guard = &epoch::pin();
        // Load the back index.
        let b = self.inner.back.load(Ordering::Acquire);
        // Is the deque empty?
        let len = b.wrapping_sub(f);
        if len <= 0 {
            return Steal::Empty;
        }
        // Reserve capacity for the stolen additional elements.
        let additional = cmp::min((len as usize - 1) / 2, MAX_BATCH);
        dest.reserve(additional);
        let additional = additional as isize;
        // Get the destination buffer and back index.
        let dest_buffer = dest.cached_buffer.get();
        let mut dest_b = dest.inner.back.load(Ordering::Relaxed);
        // Load the buffer and read the value at the front.
        let buffer = self.inner.buffer.load(Ordering::Acquire, guard);
        let value = unsafe { buffer.deref().read(f) };
        match self.flavor {
            // Steal a batch of elements from the front at once.
            Flavor::Fifo => {
                // Copy the additional elements from the source to the destination buffer.
                for i in 0..additional {
                    unsafe {
                        let value = buffer.deref().read(f.wrapping_add(i + 1));
                        dest_buffer.write(dest_b.wrapping_add(i), value);
                    }
                }
                // Try incrementing the front index to steal the batch.
                if self.inner
                    .front
                    .compare_exchange(
                        f,
                        f.wrapping_add(additional + 1),
                        Ordering::SeqCst,
                        Ordering::Relaxed,
                    )
                    .is_err()
                {
                    // We didn't steal this value, forget it.
                    mem::forget(value);
                    return Steal::Retry;
                }
                atomic::fence(Ordering::Release);
                // Success! Update the back index in the destination deque.
                //
                // This ordering could be `Relaxed`, but then thread sanitizer would falsely report
                // data races because it doesn't understand fences.
                dest.inner.back.store(dest_b.wrapping_add(additional), Ordering::Release);
                // Return the first stolen value.
                Steal::Data(value)
            }
            // Steal a batch of elements from the front one by one.
            Flavor::Lifo => {
                // Try incrementing the front index to steal the value.
                if self.inner
                    .front
                    .compare_exchange(f, f.wrapping_add(1), Ordering::SeqCst, Ordering::Relaxed)
                    .is_err()
                {
                    // We didn't steal this value, forget it.
                    mem::forget(value);
                    return Steal::Retry;
                }
                // Move the front index one step forward.
                f = f.wrapping_add(1);
                // Repeat the same procedure for the additional steals.
                for _ in 0..additional {
                    // We've already got the current front index. Now execute the fence to
                    // synchronize with other threads.
                    atomic::fence(Ordering::SeqCst);
                    // Load the back index.
                    let b = self.inner.back.load(Ordering::Acquire);
                    // Is the deque empty?
                    if b.wrapping_sub(f) <= 0 {
                        break;
                    }
                    // Read the value at the front.
                    let value = unsafe { buffer.deref().read(f) };
                    // Try incrementing the front index to steal the value.
                    if self.inner
                        .front
                        .compare_exchange(f, f.wrapping_add(1), Ordering::SeqCst, Ordering::Relaxed)
                        .is_err()
                    {
                        // We didn't steal this value, forget it and break from the loop.
                        mem::forget(value);
                        break;
                    }
                    // Write the stolen value into the destination buffer.
                    unsafe {
                        dest_buffer.write(dest_b, value);
                    }
                    // Move the source front index and the destination back index one step forward.
                    f = f.wrapping_add(1);
                    dest_b = dest_b.wrapping_add(1);
                    atomic::fence(Ordering::Release);
                    // Update the destination back index.
                    //
                    // This ordering could be `Relaxed`, but then thread sanitizer would falsely
                    // report data races because it doesn't understand fences.
                    dest.inner.back.store(dest_b, Ordering::Release);
                }
                // Return the first stolen value.
                Steal::Data(value)
            }
        }
    }
pub fn steal_many ( & self , dest : & Worker < T > ) -> Steal < T > { // Load the front index. let mut f = self . inner . front . load ( Ordering :: Acquire ) ; // A SeqCst fence is needed here. // // If the current thread is already pinned (reentrantly), we must manually issue the // fence. Otherwise, the following pinning will issue the fence anyway, so we don't // have to. if epoch :: is_pinned ( ) { atomic :: fence ( Ordering :: SeqCst ) ; } let guard = & epoch :: pin ( ) ; // Load the back index. let b = self . inner . back . load ( Ordering :: Acquire ) ; // Is the deque empty? let len = b . wrapping_sub ( f ) ; if len <= 0 { return Steal :: Empty ; } // Reserve capacity for the stolen additional elements. let additional = cmp :: min ( ( len as usize - 1 ) / 2 , MAX_BATCH ) ; dest . reserve ( additional ) ; let additional = additional as isize ; // Get the destination buffer and back index. let dest_buffer = dest . cached_buffer . get ( ) ; let mut dest_b = dest . inner . back . load ( Ordering :: Relaxed ) ; // Load the buffer and read the value at the front. let buffer = self . inner . buffer . load ( Ordering :: Acquire , guard ) ; let value = unsafe { buffer . deref ( ) . read ( f ) } ; match self . flavor { // Steal a batch of elements from the front at once. Flavor :: Fifo => { // Copy the additional elements from the source to the destination buffer. for i in 0 .. additional { unsafe { let value = buffer . deref ( ) . read ( f . wrapping_add ( i + 1 ) ) ; dest_buffer . write ( dest_b . wrapping_add ( i ) , value ) ; } } // Try incrementing the front index to steal the batch. if self . inner . front . compare_exchange ( f , f . wrapping_add ( additional + 1 ) , Ordering :: SeqCst , Ordering :: Relaxed , ) . is_err ( ) { // We didn't steal this value, forget it. mem :: forget ( value ) ; return Steal :: Retry ; } atomic :: fence ( Ordering :: Release ) ; // Success! Update the back index in the destination deque. // // This ordering could be `Relaxed`, but then thread sanitizer would falsely report // data races because it doesn't understand fences. dest . inner . back . store ( dest_b . wrapping_add ( additional ) , Ordering :: Release ) ; // Return the first stolen value. Steal :: Data ( value ) } // Steal a batch of elements from the front one by one. Flavor :: Lifo => { // Try incrementing the front index to steal the value. if self . inner . front . compare_exchange ( f , f . wrapping_add ( 1 ) , Ordering :: SeqCst , Ordering :: Relaxed ) . is_err ( ) { // We didn't steal this value, forget it. mem :: forget ( value ) ; return Steal :: Retry ; } // Move the front index one step forward. f = f . wrapping_add ( 1 ) ; // Repeat the same procedure for the additional steals. for _ in 0 .. additional { // We've already got the current front index. Now execute the fence to // synchronize with other threads. atomic :: fence ( Ordering :: SeqCst ) ; // Load the back index. let b = self . inner . back . load ( Ordering :: Acquire ) ; // Is the deque empty? if b . wrapping_sub ( f ) <= 0 { break ; } // Read the value at the front. let value = unsafe { buffer . deref ( ) . read ( f ) } ; // Try incrementing the front index to steal the value. if self . inner . front . compare_exchange ( f , f . wrapping_add ( 1 ) , Ordering :: SeqCst , Ordering :: Relaxed ) . is_err ( ) { // We didn't steal this value, forget it and break from the loop. mem :: forget ( value ) ; break ; } // Write the stolen value into the destination buffer. unsafe { dest_buffer . write ( dest_b , value ) ; } // Move the source front index and the destination back index one step forward. f = f . wrapping_add ( 1 ) ; dest_b = dest_b . wrapping_add ( 1 ) ; atomic :: fence ( Ordering :: Release ) ; // Update the destination back index. // // This ordering could be `Relaxed`, but then thread sanitizer would falsely // report data races because it doesn't understand fences. dest . inner . back . store ( dest_b , Ordering :: Release ) ; } // Return the first stolen value. Steal :: Data ( value ) } } }
Steals elements from the front of the deque.
Steals elements from the front of the deque .
&self
dest
&Worker<T>
&self
dest
&Worker<T>
examples
```
use crossbeam_deque::{self as deque, Steal}.






` ` ` use crossbeam_deque :: { self as deque Steal } .