crossbeam-channel/src/flavors/list.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! Unbounded channel implemented as a linked list. |
2 | | |
3 | | use std::cell::UnsafeCell; |
4 | | use std::marker::PhantomData; |
5 | | use std::mem::MaybeUninit; |
6 | | use std::ptr; |
7 | | use std::sync::atomic::{self, AtomicPtr, AtomicUsize, Ordering}; |
8 | | use std::time::Instant; |
9 | | |
10 | | use crossbeam_utils::{Backoff, CachePadded}; |
11 | | |
12 | | use crate::context::Context; |
13 | | use crate::err::{RecvTimeoutError, SendTimeoutError, TryRecvError, TrySendError}; |
14 | | use crate::select::{Operation, SelectHandle, Selected, Token}; |
15 | | use crate::waker::SyncWaker; |
16 | | |
17 | | // TODO(stjepang): Once we bump the minimum required Rust version to 1.28 or newer, re-apply the |
18 | | // following changes by @kleimkuhler: |
19 | | // |
20 | | // 1. https://github.com/crossbeam-rs/crossbeam-channel/pull/100 |
21 | | // 2. https://github.com/crossbeam-rs/crossbeam-channel/pull/101 |
22 | | |
23 | | // Bits indicating the state of a slot: |
24 | | // * If a message has been written into the slot, `WRITE` is set. |
25 | | // * If a message has been read from the slot, `READ` is set. |
26 | | // * If the block is being destroyed, `DESTROY` is set. |
27 | | const WRITE: usize = 1; |
28 | | const READ: usize = 2; |
29 | | const DESTROY: usize = 4; |
30 | | |
31 | | // Each block covers one "lap" of indices. |
32 | | const LAP: usize = 32; |
33 | | // The maximum number of messages a block can hold. |
34 | | const BLOCK_CAP: usize = LAP - 1; |
35 | | // How many lower bits are reserved for metadata. |
36 | | const SHIFT: usize = 1; |
37 | | // Has two different purposes: |
38 | | // * If set in head, indicates that the block is not the last one. |
39 | | // * If set in tail, indicates that the channel is disconnected. |
40 | | const MARK_BIT: usize = 1; |
41 | | |
42 | | /// A slot in a block. |
43 | | struct Slot<T> { |
44 | | /// The message. |
45 | | msg: UnsafeCell<MaybeUninit<T>>, |
46 | | |
47 | | /// The state of the slot. |
48 | | state: AtomicUsize, |
49 | | } |
50 | | |
51 | | impl<T> Slot<T> { |
52 | | /// Waits until a message is written into the slot. |
53 | 2.19M | fn wait_write(&self) { |
54 | 2.19M | let backoff = Backoff::new(); |
55 | 2.19M | while self.state.load(Ordering::Acquire) & WRITE == 0 { |
56 | 1.15k | backoff.snooze(); |
57 | 1.15k | } |
58 | 2.19M | } Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<i32>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<zero::drops::DropCounter>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<()>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<usize>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<std::time::Instant>>::wait_write <crossbeam_channel::flavors::list::Slot<()>>::wait_write Line | Count | Source | 53 | 6.86k | fn wait_write(&self) { | 54 | 6.86k | let backoff = Backoff::new(); | 55 | 6.89k | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 28 | backoff.snooze(); | 57 | 28 | } | 58 | 6.86k | } |
<crossbeam_channel::flavors::list::Slot<i32>>::wait_write Line | Count | Source | 53 | 397k | fn wait_write(&self) { | 54 | 397k | let backoff = Backoff::new(); | 55 | 397k | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 110 | backoff.snooze(); | 57 | 110 | } | 58 | 397k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::wait_write <crossbeam_channel::flavors::list::Slot<usize>>::wait_write Line | Count | Source | 53 | 10.0k | fn wait_write(&self) { | 54 | 10.0k | let backoff = Backoff::new(); | 55 | 10.0k | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 6 | backoff.snooze(); | 57 | 6 | } | 58 | 10.0k | } |
<crossbeam_channel::flavors::list::Slot<alloc::boxed::Box<isize>>>::wait_write Line | Count | Source | 53 | 1 | fn wait_write(&self) { | 54 | 1 | let backoff = Backoff::new(); | 55 | 1 | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 0 | backoff.snooze(); | 57 | 0 | } | 58 | 1 | } |
<crossbeam_channel::flavors::list::Slot<i32>>::wait_write Line | Count | Source | 53 | 98.9k | fn wait_write(&self) { | 54 | 98.9k | let backoff = Backoff::new(); | 55 | 98.9k | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 20 | backoff.snooze(); | 57 | 20 | } | 58 | 98.9k | } |
<crossbeam_channel::flavors::list::Slot<alloc::boxed::Box<i32>>>::wait_write Line | Count | Source | 53 | 12 | fn wait_write(&self) { | 54 | 12 | let backoff = Backoff::new(); | 55 | 12 | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 0 | backoff.snooze(); | 57 | 0 | } | 58 | 12 | } |
<crossbeam_channel::flavors::list::Slot<usize>>::wait_write Line | Count | Source | 53 | 202 | fn wait_write(&self) { | 54 | 202 | let backoff = Backoff::new(); | 55 | 202 | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 0 | backoff.snooze(); | 57 | 0 | } | 58 | 202 | } |
<crossbeam_channel::flavors::list::Slot<()>>::wait_write Line | Count | Source | 53 | 20.1k | fn wait_write(&self) { | 54 | 20.1k | let backoff = Backoff::new(); | 55 | 20.1k | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 18 | backoff.snooze(); | 57 | 18 | } | 58 | 20.1k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<std::time::Instant>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<array::drops::DropCounter>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<()>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<usize>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<i32>>::wait_write <crossbeam_channel::flavors::list::Slot<i32>>::wait_write Line | Count | Source | 53 | 15 | fn wait_write(&self) { | 54 | 15 | let backoff = Backoff::new(); | 55 | 15 | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 0 | backoff.snooze(); | 57 | 0 | } | 58 | 15 | } |
<crossbeam_channel::flavors::list::Slot<()>>::wait_write Line | Count | Source | 53 | 4 | fn wait_write(&self) { | 54 | 4 | let backoff = Backoff::new(); | 55 | 4 | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 0 | backoff.snooze(); | 57 | 0 | } | 58 | 4 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<()>>::wait_write <crossbeam_channel::flavors::list::Slot<i32>>::wait_write Line | Count | Source | 53 | 1 | fn wait_write(&self) { | 54 | 1 | let backoff = Backoff::new(); | 55 | 1 | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 0 | backoff.snooze(); | 57 | 0 | } | 58 | 1 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<std::time::Instant>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<std::time::Instant>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<i32>>::wait_write <crossbeam_channel::flavors::list::Slot<i32>>::wait_write Line | Count | Source | 53 | 109k | fn wait_write(&self) { | 54 | 109k | let backoff = Backoff::new(); | 55 | 110k | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 97 | backoff.snooze(); | 57 | 97 | } | 58 | 109k | } |
<crossbeam_channel::flavors::list::Slot<list::drops::DropCounter>>::wait_write Line | Count | Source | 53 | 471k | fn wait_write(&self) { | 54 | 471k | let backoff = Backoff::new(); | 55 | 471k | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 1 | backoff.snooze(); | 57 | 1 | } | 58 | 471k | } |
<crossbeam_channel::flavors::list::Slot<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::wait_write Line | Count | Source | 53 | 1.00k | fn wait_write(&self) { | 54 | 1.00k | let backoff = Backoff::new(); | 55 | 1.00k | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 0 | backoff.snooze(); | 57 | 0 | } | 58 | 1.00k | } |
<crossbeam_channel::flavors::list::Slot<()>>::wait_write Line | Count | Source | 53 | 119k | fn wait_write(&self) { | 54 | 119k | let backoff = Backoff::new(); | 55 | 119k | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 248 | backoff.snooze(); | 57 | 248 | } | 58 | 119k | } |
<crossbeam_channel::flavors::list::Slot<usize>>::wait_write Line | Count | Source | 53 | 287k | fn wait_write(&self) { | 54 | 287k | let backoff = Backoff::new(); | 55 | 287k | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 335 | backoff.snooze(); | 57 | 335 | } | 58 | 287k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<std::time::Instant>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<i64>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<usize>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<u32>>::wait_write <crossbeam_channel::flavors::list::Slot<i32>>::wait_write Line | Count | Source | 53 | 200k | fn wait_write(&self) { | 54 | 200k | let backoff = Backoff::new(); | 55 | 200k | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 0 | backoff.snooze(); | 57 | 0 | } | 58 | 200k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<alloc::string::String>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<u8>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<bool>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::wait_write <crossbeam_channel::flavors::list::Slot<i32>>::wait_write Line | Count | Source | 53 | 396k | fn wait_write(&self) { | 54 | 396k | let backoff = Backoff::new(); | 55 | 396k | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 142 | backoff.snooze(); | 57 | 142 | } | 58 | 396k | } |
<crossbeam_channel::flavors::list::Slot<usize>>::wait_write Line | Count | Source | 53 | 10.0k | fn wait_write(&self) { | 54 | 10.0k | let backoff = Backoff::new(); | 55 | 10.0k | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 0 | backoff.snooze(); | 57 | 0 | } | 58 | 10.0k | } |
<crossbeam_channel::flavors::list::Slot<()>>::wait_write Line | Count | Source | 53 | 12.1k | fn wait_write(&self) { | 54 | 12.1k | let backoff = Backoff::new(); | 55 | 12.1k | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 11 | backoff.snooze(); | 57 | 11 | } | 58 | 12.1k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<std::time::Instant>>::wait_write <crossbeam_channel::flavors::list::Slot<()>>::wait_write Line | Count | Source | 53 | 44.1k | fn wait_write(&self) { | 54 | 44.1k | let backoff = Backoff::new(); | 55 | 44.2k | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 139 | backoff.snooze(); | 57 | 139 | } | 58 | 44.1k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<std::time::Instant>>::wait_write Unexecuted instantiation: <crossbeam_channel::flavors::list::Slot<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::wait_write <crossbeam_channel::flavors::list::Slot<i32>>::wait_write Line | Count | Source | 53 | 11 | fn wait_write(&self) { | 54 | 11 | let backoff = Backoff::new(); | 55 | 11 | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 0 | backoff.snooze(); | 57 | 0 | } | 58 | 11 | } |
<crossbeam_channel::flavors::list::Slot<usize>>::wait_write Line | Count | Source | 53 | 10.0k | fn wait_write(&self) { | 54 | 10.0k | let backoff = Backoff::new(); | 55 | 10.0k | while self.state.load(Ordering::Acquire) & WRITE == 0 { | 56 | 1 | backoff.snooze(); | 57 | 1 | } | 58 | 10.0k | } |
|
59 | | } |
60 | | |
61 | | /// A block in a linked list. |
62 | | /// |
63 | | /// Each block in the list can hold up to `BLOCK_CAP` messages. |
64 | | struct Block<T> { |
65 | | /// The next block in the linked list. |
66 | | next: AtomicPtr<Block<T>>, |
67 | | |
68 | | /// Slots for messages. |
69 | | slots: [Slot<T>; BLOCK_CAP], |
70 | | } |
71 | | |
72 | | impl<T> Block<T> { |
73 | | /// Creates an empty block. |
74 | 86.5k | fn new() -> Block<T> { |
75 | 86.5k | // SAFETY: This is safe because: |
76 | 86.5k | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. |
77 | 86.5k | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. |
78 | 86.5k | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it |
79 | 86.5k | // holds a MaybeUninit. |
80 | 86.5k | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. |
81 | 86.5k | unsafe { MaybeUninit::zeroed().assume_init() } |
82 | 86.5k | } <crossbeam_channel::flavors::list::Block<i32>>::new Line | Count | Source | 74 | 12.8k | fn new() -> Block<T> { | 75 | 12.8k | // SAFETY: This is safe because: | 76 | 12.8k | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 12.8k | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 12.8k | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 12.8k | // holds a MaybeUninit. | 80 | 12.8k | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 12.8k | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 12.8k | } |
<crossbeam_channel::flavors::list::Block<usize>>::new Line | Count | Source | 74 | 325 | fn new() -> Block<T> { | 75 | 325 | // SAFETY: This is safe because: | 76 | 325 | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 325 | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 325 | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 325 | // holds a MaybeUninit. | 80 | 325 | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 325 | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 325 | } |
<crossbeam_channel::flavors::list::Block<()>>::new Line | Count | Source | 74 | 471 | fn new() -> Block<T> { | 75 | 471 | // SAFETY: This is safe because: | 76 | 471 | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 471 | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 471 | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 471 | // holds a MaybeUninit. | 80 | 471 | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 471 | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 471 | } |
<crossbeam_channel::flavors::list::Block<i32>>::new Line | Count | Source | 74 | 3.52k | fn new() -> Block<T> { | 75 | 3.52k | // SAFETY: This is safe because: | 76 | 3.52k | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 3.52k | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 3.52k | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 3.52k | // holds a MaybeUninit. | 80 | 3.52k | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 3.52k | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 3.52k | } |
<crossbeam_channel::flavors::list::Block<alloc::boxed::Box<isize>>>::new Line | Count | Source | 74 | 2 | fn new() -> Block<T> { | 75 | 2 | // SAFETY: This is safe because: | 76 | 2 | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 2 | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 2 | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 2 | // holds a MaybeUninit. | 80 | 2 | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 2 | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 2 | } |
<crossbeam_channel::flavors::list::Block<alloc::boxed::Box<i32>>>::new Line | Count | Source | 74 | 3 | fn new() -> Block<T> { | 75 | 3 | // SAFETY: This is safe because: | 76 | 3 | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 3 | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 3 | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 3 | // holds a MaybeUninit. | 80 | 3 | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 3 | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 3 | } |
<crossbeam_channel::flavors::list::Block<usize>>::new Line | Count | Source | 74 | 8 | fn new() -> Block<T> { | 75 | 8 | // SAFETY: This is safe because: | 76 | 8 | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 8 | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 8 | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 8 | // holds a MaybeUninit. | 80 | 8 | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 8 | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 8 | } |
<crossbeam_channel::flavors::list::Block<()>>::new Line | Count | Source | 74 | 729 | fn new() -> Block<T> { | 75 | 729 | // SAFETY: This is safe because: | 76 | 729 | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 729 | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 729 | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 729 | // holds a MaybeUninit. | 80 | 729 | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 729 | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 729 | } |
<crossbeam_channel::flavors::list::Block<()>>::new Line | Count | Source | 74 | 2 | fn new() -> Block<T> { | 75 | 2 | // SAFETY: This is safe because: | 76 | 2 | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 2 | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 2 | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 2 | // holds a MaybeUninit. | 80 | 2 | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 2 | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 2 | } |
<crossbeam_channel::flavors::list::Block<i32>>::new Line | Count | Source | 74 | 6 | fn new() -> Block<T> { | 75 | 6 | // SAFETY: This is safe because: | 76 | 6 | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 6 | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 6 | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 6 | // holds a MaybeUninit. | 80 | 6 | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 6 | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 6 | } |
<crossbeam_channel::flavors::list::Block<i32>>::new Line | Count | Source | 74 | 1 | fn new() -> Block<T> { | 75 | 1 | // SAFETY: This is safe because: | 76 | 1 | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 1 | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 1 | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 1 | // holds a MaybeUninit. | 80 | 1 | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 1 | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 1 | } |
<crossbeam_channel::flavors::list::Block<i32>>::new Line | Count | Source | 74 | 14.2k | fn new() -> Block<T> { | 75 | 14.2k | // SAFETY: This is safe because: | 76 | 14.2k | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 14.2k | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 14.2k | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 14.2k | // holds a MaybeUninit. | 80 | 14.2k | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 14.2k | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 14.2k | } |
<crossbeam_channel::flavors::list::Block<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::new Line | Count | Source | 74 | 1.00k | fn new() -> Block<T> { | 75 | 1.00k | // SAFETY: This is safe because: | 76 | 1.00k | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 1.00k | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 1.00k | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 1.00k | // holds a MaybeUninit. | 80 | 1.00k | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 1.00k | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 1.00k | } |
<crossbeam_channel::flavors::list::Block<list::drops::DropCounter>>::new Line | Count | Source | 74 | 16.9k | fn new() -> Block<T> { | 75 | 16.9k | // SAFETY: This is safe because: | 76 | 16.9k | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 16.9k | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 16.9k | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 16.9k | // holds a MaybeUninit. | 80 | 16.9k | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 16.9k | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 16.9k | } |
<crossbeam_channel::flavors::list::Block<()>>::new Line | Count | Source | 74 | 4.19k | fn new() -> Block<T> { | 75 | 4.19k | // SAFETY: This is safe because: | 76 | 4.19k | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 4.19k | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 4.19k | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 4.19k | // holds a MaybeUninit. | 80 | 4.19k | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 4.19k | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 4.19k | } |
<crossbeam_channel::flavors::list::Block<usize>>::new Line | Count | Source | 74 | 9.73k | fn new() -> Block<T> { | 75 | 9.73k | // SAFETY: This is safe because: | 76 | 9.73k | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 9.73k | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 9.73k | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 9.73k | // holds a MaybeUninit. | 80 | 9.73k | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 9.73k | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 9.73k | } |
<crossbeam_channel::flavors::list::Block<i32>>::new Line | Count | Source | 74 | 6.45k | fn new() -> Block<T> { | 75 | 6.45k | // SAFETY: This is safe because: | 76 | 6.45k | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 6.45k | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 6.45k | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 6.45k | // holds a MaybeUninit. | 80 | 6.45k | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 6.45k | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 6.45k | } |
<crossbeam_channel::flavors::list::Block<()>>::new Line | Count | Source | 74 | 966 | fn new() -> Block<T> { | 75 | 966 | // SAFETY: This is safe because: | 76 | 966 | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 966 | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 966 | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 966 | // holds a MaybeUninit. | 80 | 966 | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 966 | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 966 | } |
<crossbeam_channel::flavors::list::Block<usize>>::new Line | Count | Source | 74 | 325 | fn new() -> Block<T> { | 75 | 325 | // SAFETY: This is safe because: | 76 | 325 | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 325 | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 325 | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 325 | // holds a MaybeUninit. | 80 | 325 | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 325 | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 325 | } |
<crossbeam_channel::flavors::list::Block<i32>>::new Line | Count | Source | 74 | 12.8k | fn new() -> Block<T> { | 75 | 12.8k | // SAFETY: This is safe because: | 76 | 12.8k | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 12.8k | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 12.8k | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 12.8k | // holds a MaybeUninit. | 80 | 12.8k | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 12.8k | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 12.8k | } |
<crossbeam_channel::flavors::list::Block<i32>>::new Line | Count | Source | 74 | 8 | fn new() -> Block<T> { | 75 | 8 | // SAFETY: This is safe because: | 76 | 8 | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 8 | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 8 | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 8 | // holds a MaybeUninit. | 80 | 8 | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 8 | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 8 | } |
<crossbeam_channel::flavors::list::Block<()>>::new Line | Count | Source | 74 | 1.67k | fn new() -> Block<T> { | 75 | 1.67k | // SAFETY: This is safe because: | 76 | 1.67k | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 1.67k | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 1.67k | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 1.67k | // holds a MaybeUninit. | 80 | 1.67k | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 1.67k | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 1.67k | } |
<crossbeam_channel::flavors::list::Block<usize>>::new Line | Count | Source | 74 | 325 | fn new() -> Block<T> { | 75 | 325 | // SAFETY: This is safe because: | 76 | 325 | // [1] `Block::next` (AtomicPtr) may be safely zero initialized. | 77 | 325 | // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. | 78 | 325 | // [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it | 79 | 325 | // holds a MaybeUninit. | 80 | 325 | // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. | 81 | 325 | unsafe { MaybeUninit::zeroed().assume_init() } | 82 | 325 | } |
|
83 | | |
84 | | /// Waits until the next pointer is set. |
85 | 71.0k | fn wait_next(&self) -> *mut Block<T> { |
86 | 71.0k | let backoff = Backoff::new(); |
87 | | loop { |
88 | 71.5k | let next = self.next.load(Ordering::Acquire); |
89 | 71.5k | if !next.is_null() { |
90 | 71.0k | return next; |
91 | 519 | } |
92 | 519 | backoff.snooze(); |
93 | | } |
94 | 71.0k | } Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<i32>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<usize>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<()>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<zero::drops::DropCounter>>::wait_next <crossbeam_channel::flavors::list::Block<()>>::wait_next Line | Count | Source | 85 | 221 | fn wait_next(&self) -> *mut Block<T> { | 86 | 221 | let backoff = Backoff::new(); | 87 | | loop { | 88 | 222 | let next = self.next.load(Ordering::Acquire); | 89 | 222 | if !next.is_null() { | 90 | 221 | return next; | 91 | 1 | } | 92 | 1 | backoff.snooze(); | 93 | | } | 94 | 221 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<std::time::Instant>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::wait_next <crossbeam_channel::flavors::list::Block<usize>>::wait_next Line | Count | Source | 85 | 322 | fn wait_next(&self) -> *mut Block<T> { | 86 | 322 | let backoff = Backoff::new(); | 87 | | loop { | 88 | 330 | let next = self.next.load(Ordering::Acquire); | 89 | 330 | if !next.is_null() { | 90 | 322 | return next; | 91 | 8 | } | 92 | 8 | backoff.snooze(); | 93 | | } | 94 | 322 | } |
<crossbeam_channel::flavors::list::Block<i32>>::wait_next Line | Count | Source | 85 | 12.8k | fn wait_next(&self) -> *mut Block<T> { | 86 | 12.8k | let backoff = Backoff::new(); | 87 | | loop { | 88 | 12.9k | let next = self.next.load(Ordering::Acquire); | 89 | 12.9k | if !next.is_null() { | 90 | 12.8k | return next; | 91 | 14 | } | 92 | 14 | backoff.snooze(); | 93 | | } | 94 | 12.8k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::boxed::Box<isize>>>::wait_next <crossbeam_channel::flavors::list::Block<i32>>::wait_next Line | Count | Source | 85 | 3.22k | fn wait_next(&self) -> *mut Block<T> { | 86 | 3.22k | let backoff = Backoff::new(); | 87 | | loop { | 88 | 3.22k | let next = self.next.load(Ordering::Acquire); | 89 | 3.22k | if !next.is_null() { | 90 | 3.22k | return next; | 91 | 1 | } | 92 | 1 | backoff.snooze(); | 93 | | } | 94 | 3.22k | } |
<crossbeam_channel::flavors::list::Block<()>>::wait_next Line | Count | Source | 85 | 647 | fn wait_next(&self) -> *mut Block<T> { | 86 | 647 | let backoff = Backoff::new(); | 87 | | loop { | 88 | 651 | let next = self.next.load(Ordering::Acquire); | 89 | 651 | if !next.is_null() { | 90 | 647 | return next; | 91 | 4 | } | 92 | 4 | backoff.snooze(); | 93 | | } | 94 | 647 | } |
<crossbeam_channel::flavors::list::Block<usize>>::wait_next Line | Count | Source | 85 | 6 | fn wait_next(&self) -> *mut Block<T> { | 86 | 6 | let backoff = Backoff::new(); | 87 | | loop { | 88 | 6 | let next = self.next.load(Ordering::Acquire); | 89 | 6 | if !next.is_null() { | 90 | 6 | return next; | 91 | 0 | } | 92 | 0 | backoff.snooze(); | 93 | | } | 94 | 6 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::boxed::Box<i32>>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<()>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<std::time::Instant>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<array::drops::DropCounter>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<i32>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<()>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<usize>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<()>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<i32>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<()>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<std::time::Instant>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<i32>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<()>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<std::time::Instant>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<i32>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<()>>::wait_next <crossbeam_channel::flavors::list::Block<i32>>::wait_next Line | Count | Source | 85 | 3.22k | fn wait_next(&self) -> *mut Block<T> { | 86 | 3.22k | let backoff = Backoff::new(); | 87 | | loop { | 88 | 3.23k | let next = self.next.load(Ordering::Acquire); | 89 | 3.23k | if !next.is_null() { | 90 | 3.22k | return next; | 91 | 8 | } | 92 | 8 | backoff.snooze(); | 93 | | } | 94 | 3.22k | } |
<crossbeam_channel::flavors::list::Block<usize>>::wait_next Line | Count | Source | 85 | 9.65k | fn wait_next(&self) -> *mut Block<T> { | 86 | 9.65k | let backoff = Backoff::new(); | 87 | | loop { | 88 | 9.87k | let next = self.next.load(Ordering::Acquire); | 89 | 9.87k | if !next.is_null() { | 90 | 9.65k | return next; | 91 | 214 | } | 92 | 214 | backoff.snooze(); | 93 | | } | 94 | 9.65k | } |
<crossbeam_channel::flavors::list::Block<()>>::wait_next Line | Count | Source | 85 | 3.86k | fn wait_next(&self) -> *mut Block<T> { | 86 | 3.86k | let backoff = Backoff::new(); | 87 | | loop { | 88 | 4.08k | let next = self.next.load(Ordering::Acquire); | 89 | 4.08k | if !next.is_null() { | 90 | 3.86k | return next; | 91 | 215 | } | 92 | 215 | backoff.snooze(); | 93 | | } | 94 | 3.86k | } |
<crossbeam_channel::flavors::list::Block<list::drops::DropCounter>>::wait_next Line | Count | Source | 85 | 15.1k | fn wait_next(&self) -> *mut Block<T> { | 86 | 15.1k | let backoff = Backoff::new(); | 87 | | loop { | 88 | 15.1k | let next = self.next.load(Ordering::Acquire); | 89 | 15.1k | if !next.is_null() { | 90 | 15.1k | return next; | 91 | 0 | } | 92 | 0 | backoff.snooze(); | 93 | | } | 94 | 15.1k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<usize>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<u32>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<std::time::Instant>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<i64>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<bool>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<u8>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<()>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::string::String>>::wait_next <crossbeam_channel::flavors::list::Block<i32>>::wait_next Line | Count | Source | 85 | 6.45k | fn wait_next(&self) -> *mut Block<T> { | 86 | 6.45k | let backoff = Backoff::new(); | 87 | | loop { | 88 | 6.45k | let next = self.next.load(Ordering::Acquire); | 89 | 6.45k | if !next.is_null() { | 90 | 6.45k | return next; | 91 | 0 | } | 92 | 0 | backoff.snooze(); | 93 | | } | 94 | 6.45k | } |
<crossbeam_channel::flavors::list::Block<()>>::wait_next Line | Count | Source | 85 | 394 | fn wait_next(&self) -> *mut Block<T> { | 86 | 394 | let backoff = Backoff::new(); | 87 | | loop { | 88 | 395 | let next = self.next.load(Ordering::Acquire); | 89 | 395 | if !next.is_null() { | 90 | 394 | return next; | 91 | 1 | } | 92 | 1 | backoff.snooze(); | 93 | | } | 94 | 394 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::wait_next <crossbeam_channel::flavors::list::Block<i32>>::wait_next Line | Count | Source | 85 | 12.8k | fn wait_next(&self) -> *mut Block<T> { | 86 | 12.8k | let backoff = Backoff::new(); | 87 | | loop { | 88 | 12.9k | let next = self.next.load(Ordering::Acquire); | 89 | 12.9k | if !next.is_null() { | 90 | 12.8k | return next; | 91 | 48 | } | 92 | 48 | backoff.snooze(); | 93 | | } | 94 | 12.8k | } |
<crossbeam_channel::flavors::list::Block<usize>>::wait_next Line | Count | Source | 85 | 322 | fn wait_next(&self) -> *mut Block<T> { | 86 | 322 | let backoff = Backoff::new(); | 87 | | loop { | 88 | 324 | let next = self.next.load(Ordering::Acquire); | 89 | 324 | if !next.is_null() { | 90 | 322 | return next; | 91 | 2 | } | 92 | 2 | backoff.snooze(); | 93 | | } | 94 | 322 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<std::time::Instant>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::wait_next <crossbeam_channel::flavors::list::Block<usize>>::wait_next Line | Count | Source | 85 | 322 | fn wait_next(&self) -> *mut Block<T> { | 86 | 322 | let backoff = Backoff::new(); | 87 | | loop { | 88 | 322 | let next = self.next.load(Ordering::Acquire); | 89 | 322 | if !next.is_null() { | 90 | 322 | return next; | 91 | 0 | } | 92 | 0 | backoff.snooze(); | 93 | | } | 94 | 322 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<i32>>::wait_next Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<std::time::Instant>>::wait_next <crossbeam_channel::flavors::list::Block<()>>::wait_next Line | Count | Source | 85 | 1.42k | fn wait_next(&self) -> *mut Block<T> { | 86 | 1.42k | let backoff = Backoff::new(); | 87 | | loop { | 88 | 1.42k | let next = self.next.load(Ordering::Acquire); | 89 | 1.42k | if !next.is_null() { | 90 | 1.42k | return next; | 91 | 3 | } | 92 | 3 | backoff.snooze(); | 93 | | } | 94 | 1.42k | } |
|
95 | | |
96 | | /// Sets the `DESTROY` bit in slots starting from `start` and destroys the block. |
97 | 71.0k | unsafe fn destroy(this: *mut Block<T>, start: usize) { |
98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has |
99 | | // begun destruction of the block. |
100 | 2.07M | for i in start..BLOCK_CAP - 171.0k { |
101 | 2.07M | let slot = (*this).slots.get_unchecked(i); |
102 | | |
103 | | // Mark the `DESTROY` bit if a thread is still using the slot. |
104 | 2.07M | if slot.state.load(Ordering::Acquire) & READ == 0 |
105 | 18 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 |
106 | | { |
107 | | // If a thread is still using the slot, it will continue destruction of the block. |
108 | 18 | return; |
109 | 2.08M | } |
110 | | } |
111 | | |
112 | | // No thread is using the block, now it is safe to destroy it. |
113 | 71.0k | drop(Box::from_raw(this)); |
114 | 71.0k | } Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<usize>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<i32>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<zero::drops::DropCounter>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<()>>::destroy <crossbeam_channel::flavors::list::Block<i32>>::destroy Line | Count | Source | 97 | 12.8k | unsafe fn destroy(this: *mut Block<T>, start: usize) { | 98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has | 99 | | // begun destruction of the block. | 100 | 362k | for i in start..BLOCK_CAP - 112.8k { | 101 | 362k | let slot = (*this).slots.get_unchecked(i); | 102 | | | 103 | | // Mark the `DESTROY` bit if a thread is still using the slot. | 104 | 362k | if slot.state.load(Ordering::Acquire) & READ == 0 | 105 | 0 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 | 106 | | { | 107 | | // If a thread is still using the slot, it will continue destruction of the block. | 108 | 0 | return; | 109 | 363k | } | 110 | | } | 111 | | | 112 | | // No thread is using the block, now it is safe to destroy it. | 113 | 12.8k | drop(Box::from_raw(this)); | 114 | 12.8k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::destroy <crossbeam_channel::flavors::list::Block<usize>>::destroy Line | Count | Source | 97 | 322 | unsafe fn destroy(this: *mut Block<T>, start: usize) { | 98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has | 99 | | // begun destruction of the block. | 100 | 9.66k | for i in start..BLOCK_CAP - 1322 { | 101 | 9.66k | let slot = (*this).slots.get_unchecked(i); | 102 | | | 103 | | // Mark the `DESTROY` bit if a thread is still using the slot. | 104 | 9.66k | if slot.state.load(Ordering::Acquire) & READ == 0 | 105 | 0 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 | 106 | | { | 107 | | // If a thread is still using the slot, it will continue destruction of the block. | 108 | 0 | return; | 109 | 9.66k | } | 110 | | } | 111 | | | 112 | | // No thread is using the block, now it is safe to destroy it. | 113 | 322 | drop(Box::from_raw(this)); | 114 | 322 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<std::time::Instant>>::destroy <crossbeam_channel::flavors::list::Block<()>>::destroy Line | Count | Source | 97 | 221 | unsafe fn destroy(this: *mut Block<T>, start: usize) { | 98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has | 99 | | // begun destruction of the block. | 100 | 6.63k | for i in start..BLOCK_CAP - 1221 { | 101 | 6.63k | let slot = (*this).slots.get_unchecked(i); | 102 | | | 103 | | // Mark the `DESTROY` bit if a thread is still using the slot. | 104 | 6.63k | if slot.state.load(Ordering::Acquire) & READ == 0 | 105 | 0 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 | 106 | | { | 107 | | // If a thread is still using the slot, it will continue destruction of the block. | 108 | 0 | return; | 109 | 6.63k | } | 110 | | } | 111 | | | 112 | | // No thread is using the block, now it is safe to destroy it. | 113 | 221 | drop(Box::from_raw(this)); | 114 | 221 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::boxed::Box<i32>>>::destroy <crossbeam_channel::flavors::list::Block<usize>>::destroy Line | Count | Source | 97 | 6 | unsafe fn destroy(this: *mut Block<T>, start: usize) { | 98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has | 99 | | // begun destruction of the block. | 100 | 180 | for i in start..BLOCK_CAP - 16 { | 101 | 180 | let slot = (*this).slots.get_unchecked(i); | 102 | | | 103 | | // Mark the `DESTROY` bit if a thread is still using the slot. | 104 | 180 | if slot.state.load(Ordering::Acquire) & READ == 0 | 105 | 0 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 | 106 | | { | 107 | | // If a thread is still using the slot, it will continue destruction of the block. | 108 | 0 | return; | 109 | 180 | } | 110 | | } | 111 | | | 112 | | // No thread is using the block, now it is safe to destroy it. | 113 | 6 | drop(Box::from_raw(this)); | 114 | 6 | } |
<crossbeam_channel::flavors::list::Block<()>>::destroy Line | Count | Source | 97 | 647 | unsafe fn destroy(this: *mut Block<T>, start: usize) { | 98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has | 99 | | // begun destruction of the block. | 100 | 19.4k | for i in start..BLOCK_CAP - 1647 { | 101 | 19.4k | let slot = (*this).slots.get_unchecked(i); | 102 | | | 103 | | // Mark the `DESTROY` bit if a thread is still using the slot. | 104 | 19.4k | if slot.state.load(Ordering::Acquire) & READ == 0 | 105 | 0 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 | 106 | | { | 107 | | // If a thread is still using the slot, it will continue destruction of the block. | 108 | 0 | return; | 109 | 19.4k | } | 110 | | } | 111 | | | 112 | | // No thread is using the block, now it is safe to destroy it. | 113 | 647 | drop(Box::from_raw(this)); | 114 | 647 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::boxed::Box<isize>>>::destroy <crossbeam_channel::flavors::list::Block<i32>>::destroy Line | Count | Source | 97 | 3.22k | unsafe fn destroy(this: *mut Block<T>, start: usize) { | 98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has | 99 | | // begun destruction of the block. | 100 | 96.6k | for i in start..BLOCK_CAP - 13.22k { | 101 | 96.6k | let slot = (*this).slots.get_unchecked(i); | 102 | | | 103 | | // Mark the `DESTROY` bit if a thread is still using the slot. | 104 | 96.6k | if slot.state.load(Ordering::Acquire) & READ == 0 | 105 | 0 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 | 106 | | { | 107 | | // If a thread is still using the slot, it will continue destruction of the block. | 108 | 0 | return; | 109 | 96.7k | } | 110 | | } | 111 | | | 112 | | // No thread is using the block, now it is safe to destroy it. | 113 | 3.22k | drop(Box::from_raw(this)); | 114 | 3.22k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<std::time::Instant>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<()>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<usize>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<i32>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<array::drops::DropCounter>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<i32>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<()>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<()>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<i32>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<std::time::Instant>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<std::time::Instant>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<i32>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::destroy <crossbeam_channel::flavors::list::Block<()>>::destroy Line | Count | Source | 97 | 3.86k | unsafe fn destroy(this: *mut Block<T>, start: usize) { | 98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has | 99 | | // begun destruction of the block. | 100 | 115k | for i in start..BLOCK_CAP - 13.86k { | 101 | 115k | let slot = (*this).slots.get_unchecked(i); | 102 | | | 103 | | // Mark the `DESTROY` bit if a thread is still using the slot. | 104 | 115k | if slot.state.load(Ordering::Acquire) & READ == 0 | 105 | 0 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 | 106 | | { | 107 | | // If a thread is still using the slot, it will continue destruction of the block. | 108 | 0 | return; | 109 | 115k | } | 110 | | } | 111 | | | 112 | | // No thread is using the block, now it is safe to destroy it. | 113 | 3.86k | drop(Box::from_raw(this)); | 114 | 3.86k | } |
<crossbeam_channel::flavors::list::Block<usize>>::destroy Line | Count | Source | 97 | 9.66k | unsafe fn destroy(this: *mut Block<T>, start: usize) { | 98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has | 99 | | // begun destruction of the block. | 100 | 288k | for i in start..BLOCK_CAP - 19.66k { | 101 | 288k | let slot = (*this).slots.get_unchecked(i); | 102 | | | 103 | | // Mark the `DESTROY` bit if a thread is still using the slot. | 104 | 288k | if slot.state.load(Ordering::Acquire) & READ == 0 | 105 | 5 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 | 106 | | { | 107 | | // If a thread is still using the slot, it will continue destruction of the block. | 108 | 5 | return; | 109 | 289k | } | 110 | | } | 111 | | | 112 | | // No thread is using the block, now it is safe to destroy it. | 113 | 9.66k | drop(Box::from_raw(this)); | 114 | 9.67k | } |
<crossbeam_channel::flavors::list::Block<i32>>::destroy Line | Count | Source | 97 | 3.23k | unsafe fn destroy(this: *mut Block<T>, start: usize) { | 98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has | 99 | | // begun destruction of the block. | 100 | 96.7k | for i in start..BLOCK_CAP - 13.23k { | 101 | 96.7k | let slot = (*this).slots.get_unchecked(i); | 102 | | | 103 | | // Mark the `DESTROY` bit if a thread is still using the slot. | 104 | 96.7k | if slot.state.load(Ordering::Acquire) & READ == 0 | 105 | 13 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 | 106 | | { | 107 | | // If a thread is still using the slot, it will continue destruction of the block. | 108 | 13 | return; | 109 | 96.7k | } | 110 | | } | 111 | | | 112 | | // No thread is using the block, now it is safe to destroy it. | 113 | 3.22k | drop(Box::from_raw(this)); | 114 | 3.23k | } |
<crossbeam_channel::flavors::list::Block<list::drops::DropCounter>>::destroy Line | Count | Source | 97 | 15.1k | unsafe fn destroy(this: *mut Block<T>, start: usize) { | 98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has | 99 | | // begun destruction of the block. | 100 | 455k | for i in start..BLOCK_CAP - 115.1k { | 101 | 455k | let slot = (*this).slots.get_unchecked(i); | 102 | | | 103 | | // Mark the `DESTROY` bit if a thread is still using the slot. | 104 | 455k | if slot.state.load(Ordering::Acquire) & READ == 0 | 105 | 0 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 | 106 | | { | 107 | | // If a thread is still using the slot, it will continue destruction of the block. | 108 | 0 | return; | 109 | 455k | } | 110 | | } | 111 | | | 112 | | // No thread is using the block, now it is safe to destroy it. | 113 | 15.1k | drop(Box::from_raw(this)); | 114 | 15.1k | } |
<crossbeam_channel::flavors::list::Block<i32>>::destroy Line | Count | Source | 97 | 6.45k | unsafe fn destroy(this: *mut Block<T>, start: usize) { | 98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has | 99 | | // begun destruction of the block. | 100 | 193k | for i in start..BLOCK_CAP - 16.45k { | 101 | 193k | let slot = (*this).slots.get_unchecked(i); | 102 | | | 103 | | // Mark the `DESTROY` bit if a thread is still using the slot. | 104 | 193k | if slot.state.load(Ordering::Acquire) & READ == 0 | 105 | 0 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 | 106 | | { | 107 | | // If a thread is still using the slot, it will continue destruction of the block. | 108 | 0 | return; | 109 | 193k | } | 110 | | } | 111 | | | 112 | | // No thread is using the block, now it is safe to destroy it. | 113 | 6.45k | drop(Box::from_raw(this)); | 114 | 6.45k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::string::String>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<u8>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<bool>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<std::time::Instant>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<i64>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<usize>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<u32>>::destroy <crossbeam_channel::flavors::list::Block<()>>::destroy Line | Count | Source | 97 | 394 | unsafe fn destroy(this: *mut Block<T>, start: usize) { | 98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has | 99 | | // begun destruction of the block. | 100 | 11.8k | for i in start..BLOCK_CAP - 1394 { | 101 | 11.8k | let slot = (*this).slots.get_unchecked(i); | 102 | | | 103 | | // Mark the `DESTROY` bit if a thread is still using the slot. | 104 | 11.8k | if slot.state.load(Ordering::Acquire) & READ == 0 | 105 | 0 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 | 106 | | { | 107 | | // If a thread is still using the slot, it will continue destruction of the block. | 108 | 0 | return; | 109 | 11.8k | } | 110 | | } | 111 | | | 112 | | // No thread is using the block, now it is safe to destroy it. | 113 | 394 | drop(Box::from_raw(this)); | 114 | 394 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<std::time::Instant>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::destroy <crossbeam_channel::flavors::list::Block<i32>>::destroy Line | Count | Source | 97 | 12.8k | unsafe fn destroy(this: *mut Block<T>, start: usize) { | 98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has | 99 | | // begun destruction of the block. | 100 | 359k | for i in start..BLOCK_CAP - 112.8k { | 101 | 359k | let slot = (*this).slots.get_unchecked(i); | 102 | | | 103 | | // Mark the `DESTROY` bit if a thread is still using the slot. | 104 | 359k | if slot.state.load(Ordering::Acquire) & READ == 0 | 105 | 0 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 | 106 | | { | 107 | | // If a thread is still using the slot, it will continue destruction of the block. | 108 | 0 | return; | 109 | 361k | } | 110 | | } | 111 | | | 112 | | // No thread is using the block, now it is safe to destroy it. | 113 | 12.8k | drop(Box::from_raw(this)); | 114 | 12.8k | } |
<crossbeam_channel::flavors::list::Block<usize>>::destroy Line | Count | Source | 97 | 322 | unsafe fn destroy(this: *mut Block<T>, start: usize) { | 98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has | 99 | | // begun destruction of the block. | 100 | 9.66k | for i in start..BLOCK_CAP - 1322 { | 101 | 9.66k | let slot = (*this).slots.get_unchecked(i); | 102 | | | 103 | | // Mark the `DESTROY` bit if a thread is still using the slot. | 104 | 9.66k | if slot.state.load(Ordering::Acquire) & READ == 0 | 105 | 0 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 | 106 | | { | 107 | | // If a thread is still using the slot, it will continue destruction of the block. | 108 | 0 | return; | 109 | 9.66k | } | 110 | | } | 111 | | | 112 | | // No thread is using the block, now it is safe to destroy it. | 113 | 322 | drop(Box::from_raw(this)); | 114 | 322 | } |
<crossbeam_channel::flavors::list::Block<()>>::destroy Line | Count | Source | 97 | 1.42k | unsafe fn destroy(this: *mut Block<T>, start: usize) { | 98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has | 99 | | // begun destruction of the block. | 100 | 42.7k | for i in start..BLOCK_CAP - 11.42k { | 101 | 42.7k | let slot = (*this).slots.get_unchecked(i); | 102 | | | 103 | | // Mark the `DESTROY` bit if a thread is still using the slot. | 104 | 42.7k | if slot.state.load(Ordering::Acquire) & READ == 0 | 105 | 0 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 | 106 | | { | 107 | | // If a thread is still using the slot, it will continue destruction of the block. | 108 | 0 | return; | 109 | 42.6k | } | 110 | | } | 111 | | | 112 | | // No thread is using the block, now it is safe to destroy it. | 113 | 1.42k | drop(Box::from_raw(this)); | 114 | 1.42k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<std::time::Instant>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::destroy Unexecuted instantiation: <crossbeam_channel::flavors::list::Block<i32>>::destroy <crossbeam_channel::flavors::list::Block<usize>>::destroy Line | Count | Source | 97 | 322 | unsafe fn destroy(this: *mut Block<T>, start: usize) { | 98 | | // It is not necessary to set the `DESTROY` bit in the last slot because that slot has | 99 | | // begun destruction of the block. | 100 | 9.66k | for i in start..BLOCK_CAP - 1322 { | 101 | 9.66k | let slot = (*this).slots.get_unchecked(i); | 102 | | | 103 | | // Mark the `DESTROY` bit if a thread is still using the slot. | 104 | 9.66k | if slot.state.load(Ordering::Acquire) & READ == 0 | 105 | 0 | && slot.state.fetch_or(DESTROY, Ordering::AcqRel) & READ == 0 | 106 | | { | 107 | | // If a thread is still using the slot, it will continue destruction of the block. | 108 | 0 | return; | 109 | 9.66k | } | 110 | | } | 111 | | | 112 | | // No thread is using the block, now it is safe to destroy it. | 113 | 322 | drop(Box::from_raw(this)); | 114 | 322 | } |
|
115 | | } |
116 | | |
117 | | /// A position in a channel. |
118 | 0 | #[derive(Debug)] |
119 | | struct Position<T> { |
120 | | /// The index in the channel. |
121 | | index: AtomicUsize, |
122 | | |
123 | | /// The block in the linked list. |
124 | | block: AtomicPtr<Block<T>>, |
125 | | } |
126 | | |
127 | | /// The token type for the list flavor. |
128 | 0 | #[derive(Debug)] |
129 | | pub struct ListToken { |
130 | | /// The block of slots. |
131 | | block: *const u8, |
132 | | |
133 | | /// The offset into the block. |
134 | | offset: usize, |
135 | | } |
136 | | |
137 | | impl Default for ListToken { |
138 | | #[inline] |
139 | 88.1M | fn default() -> Self { |
140 | 88.1M | ListToken { |
141 | 88.1M | block: ptr::null(), |
142 | 88.1M | offset: 0, |
143 | 88.1M | } |
144 | 88.1M | } <crossbeam_channel::flavors::list::ListToken as core::default::Default>::default Line | Count | Source | 139 | 733k | fn default() -> Self { | 140 | 733k | ListToken { | 141 | 733k | block: ptr::null(), | 142 | 733k | offset: 0, | 143 | 733k | } | 144 | 733k | } |
<crossbeam_channel::flavors::list::ListToken as core::default::Default>::default Line | Count | Source | 139 | 9.91M | fn default() -> Self { | 140 | 9.91M | ListToken { | 141 | 9.91M | block: ptr::null(), | 142 | 9.91M | offset: 0, | 143 | 9.91M | } | 144 | 9.91M | } |
<crossbeam_channel::flavors::list::ListToken as core::default::Default>::default Line | Count | Source | 139 | 5.37M | fn default() -> Self { | 140 | 5.37M | ListToken { | 141 | 5.37M | block: ptr::null(), | 142 | 5.37M | offset: 0, | 143 | 5.37M | } | 144 | 5.37M | } |
<crossbeam_channel::flavors::list::ListToken as core::default::Default>::default Line | Count | Source | 139 | 281k | fn default() -> Self { | 140 | 281k | ListToken { | 141 | 281k | block: ptr::null(), | 142 | 281k | offset: 0, | 143 | 281k | } | 144 | 281k | } |
<crossbeam_channel::flavors::list::ListToken as core::default::Default>::default Line | Count | Source | 139 | 1.54M | fn default() -> Self { | 140 | 1.54M | ListToken { | 141 | 1.54M | block: ptr::null(), | 142 | 1.54M | offset: 0, | 143 | 1.54M | } | 144 | 1.54M | } |
<crossbeam_channel::flavors::list::ListToken as core::default::Default>::default Line | Count | Source | 139 | 127 | fn default() -> Self { | 140 | 127 | ListToken { | 141 | 127 | block: ptr::null(), | 142 | 127 | offset: 0, | 143 | 127 | } | 144 | 127 | } |
<crossbeam_channel::flavors::list::ListToken as core::default::Default>::default Line | Count | Source | 139 | 3 | fn default() -> Self { | 140 | 3 | ListToken { | 141 | 3 | block: ptr::null(), | 142 | 3 | offset: 0, | 143 | 3 | } | 144 | 3 | } |
<crossbeam_channel::flavors::list::ListToken as core::default::Default>::default Line | Count | Source | 139 | 1.59M | fn default() -> Self { | 140 | 1.59M | ListToken { | 141 | 1.59M | block: ptr::null(), | 142 | 1.59M | offset: 0, | 143 | 1.59M | } | 144 | 1.59M | } |
<crossbeam_channel::flavors::list::ListToken as core::default::Default>::default Line | Count | Source | 139 | 1.48M | fn default() -> Self { | 140 | 1.48M | ListToken { | 141 | 1.48M | block: ptr::null(), | 142 | 1.48M | offset: 0, | 143 | 1.48M | } | 144 | 1.48M | } |
<crossbeam_channel::flavors::list::ListToken as core::default::Default>::default Line | Count | Source | 139 | 66.9M | fn default() -> Self { | 140 | 66.9M | ListToken { | 141 | 66.9M | block: ptr::null(), | 142 | 66.9M | offset: 0, | 143 | 66.9M | } | 144 | 66.9M | } |
<crossbeam_channel::flavors::list::ListToken as core::default::Default>::default Line | Count | Source | 139 | 291k | fn default() -> Self { | 140 | 291k | ListToken { | 141 | 291k | block: ptr::null(), | 142 | 291k | offset: 0, | 143 | 291k | } | 144 | 291k | } |
|
145 | | } |
146 | | |
147 | | /// Unbounded channel implemented as a linked list. |
148 | | /// |
149 | | /// Each message sent into the channel is assigned a sequence number, i.e. an index. Indices are |
150 | | /// represented as numbers of type `usize` and wrap on overflow. |
151 | | /// |
152 | | /// Consecutive messages are grouped into blocks in order to put less pressure on the allocator and |
153 | | /// improve cache efficiency. |
154 | | pub(crate) struct Channel<T> { |
155 | | /// The head of the channel. |
156 | | head: CachePadded<Position<T>>, |
157 | | |
158 | | /// The tail of the channel. |
159 | | tail: CachePadded<Position<T>>, |
160 | | |
161 | | /// Receivers waiting while the channel is empty and not disconnected. |
162 | | receivers: SyncWaker, |
163 | | |
164 | | /// Indicates that dropping a `Channel<T>` may drop messages of type `T`. |
165 | | _marker: PhantomData<T>, |
166 | | } |
167 | | |
168 | | impl<T> Channel<T> { |
169 | | /// Creates a new unbounded channel. |
170 | 11.3k | pub(crate) fn new() -> Self { |
171 | 11.3k | Channel { |
172 | 11.3k | head: CachePadded::new(Position { |
173 | 11.3k | block: AtomicPtr::new(ptr::null_mut()), |
174 | 11.3k | index: AtomicUsize::new(0), |
175 | 11.3k | }), |
176 | 11.3k | tail: CachePadded::new(Position { |
177 | 11.3k | block: AtomicPtr::new(ptr::null_mut()), |
178 | 11.3k | index: AtomicUsize::new(0), |
179 | 11.3k | }), |
180 | 11.3k | receivers: SyncWaker::new(), |
181 | 11.3k | _marker: PhantomData, |
182 | 11.3k | } |
183 | 11.3k | } <crossbeam_channel::flavors::list::Channel<usize>>::new Line | Count | Source | 170 | 3 | pub(crate) fn new() -> Self { | 171 | 3 | Channel { | 172 | 3 | head: CachePadded::new(Position { | 173 | 3 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 3 | index: AtomicUsize::new(0), | 175 | 3 | }), | 176 | 3 | tail: CachePadded::new(Position { | 177 | 3 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 3 | index: AtomicUsize::new(0), | 179 | 3 | }), | 180 | 3 | receivers: SyncWaker::new(), | 181 | 3 | _marker: PhantomData, | 182 | 3 | } | 183 | 3 | } |
<crossbeam_channel::flavors::list::Channel<()>>::new Line | Count | Source | 170 | 9 | pub(crate) fn new() -> Self { | 171 | 9 | Channel { | 172 | 9 | head: CachePadded::new(Position { | 173 | 9 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 9 | index: AtomicUsize::new(0), | 175 | 9 | }), | 176 | 9 | tail: CachePadded::new(Position { | 177 | 9 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 9 | index: AtomicUsize::new(0), | 179 | 9 | }), | 180 | 9 | receivers: SyncWaker::new(), | 181 | 9 | _marker: PhantomData, | 182 | 9 | } | 183 | 9 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::new Line | Count | Source | 170 | 23 | pub(crate) fn new() -> Self { | 171 | 23 | Channel { | 172 | 23 | head: CachePadded::new(Position { | 173 | 23 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 23 | index: AtomicUsize::new(0), | 175 | 23 | }), | 176 | 23 | tail: CachePadded::new(Position { | 177 | 23 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 23 | index: AtomicUsize::new(0), | 179 | 23 | }), | 180 | 23 | receivers: SyncWaker::new(), | 181 | 23 | _marker: PhantomData, | 182 | 23 | } | 183 | 23 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::new Line | Count | Source | 170 | 59 | pub(crate) fn new() -> Self { | 171 | 59 | Channel { | 172 | 59 | head: CachePadded::new(Position { | 173 | 59 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 59 | index: AtomicUsize::new(0), | 175 | 59 | }), | 176 | 59 | tail: CachePadded::new(Position { | 177 | 59 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 59 | index: AtomicUsize::new(0), | 179 | 59 | }), | 180 | 59 | receivers: SyncWaker::new(), | 181 | 59 | _marker: PhantomData, | 182 | 59 | } | 183 | 59 | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<i32>>>::new Line | Count | Source | 170 | 5 | pub(crate) fn new() -> Self { | 171 | 5 | Channel { | 172 | 5 | head: CachePadded::new(Position { | 173 | 5 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 5 | index: AtomicUsize::new(0), | 175 | 5 | }), | 176 | 5 | tail: CachePadded::new(Position { | 177 | 5 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 5 | index: AtomicUsize::new(0), | 179 | 5 | }), | 180 | 5 | receivers: SyncWaker::new(), | 181 | 5 | _marker: PhantomData, | 182 | 5 | } | 183 | 5 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::new Line | Count | Source | 170 | 2 | pub(crate) fn new() -> Self { | 171 | 2 | Channel { | 172 | 2 | head: CachePadded::new(Position { | 173 | 2 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 2 | index: AtomicUsize::new(0), | 175 | 2 | }), | 176 | 2 | tail: CachePadded::new(Position { | 177 | 2 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 2 | index: AtomicUsize::new(0), | 179 | 2 | }), | 180 | 2 | receivers: SyncWaker::new(), | 181 | 2 | _marker: PhantomData, | 182 | 2 | } | 183 | 2 | } |
<crossbeam_channel::flavors::list::Channel<()>>::new Line | Count | Source | 170 | 35 | pub(crate) fn new() -> Self { | 171 | 35 | Channel { | 172 | 35 | head: CachePadded::new(Position { | 173 | 35 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 35 | index: AtomicUsize::new(0), | 175 | 35 | }), | 176 | 35 | tail: CachePadded::new(Position { | 177 | 35 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 35 | index: AtomicUsize::new(0), | 179 | 35 | }), | 180 | 35 | receivers: SyncWaker::new(), | 181 | 35 | _marker: PhantomData, | 182 | 35 | } | 183 | 35 | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<isize>>>::new Line | Count | Source | 170 | 3 | pub(crate) fn new() -> Self { | 171 | 3 | Channel { | 172 | 3 | head: CachePadded::new(Position { | 173 | 3 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 3 | index: AtomicUsize::new(0), | 175 | 3 | }), | 176 | 3 | tail: CachePadded::new(Position { | 177 | 3 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 3 | index: AtomicUsize::new(0), | 179 | 3 | }), | 180 | 3 | receivers: SyncWaker::new(), | 181 | 3 | _marker: PhantomData, | 182 | 3 | } | 183 | 3 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::new Line | Count | Source | 170 | 7 | pub(crate) fn new() -> Self { | 171 | 7 | Channel { | 172 | 7 | head: CachePadded::new(Position { | 173 | 7 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 7 | index: AtomicUsize::new(0), | 175 | 7 | }), | 176 | 7 | tail: CachePadded::new(Position { | 177 | 7 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 7 | index: AtomicUsize::new(0), | 179 | 7 | }), | 180 | 7 | receivers: SyncWaker::new(), | 181 | 7 | _marker: PhantomData, | 182 | 7 | } | 183 | 7 | } |
<crossbeam_channel::flavors::list::Channel<()>>::new Line | Count | Source | 170 | 1 | pub(crate) fn new() -> Self { | 171 | 1 | Channel { | 172 | 1 | head: CachePadded::new(Position { | 173 | 1 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 1 | index: AtomicUsize::new(0), | 175 | 1 | }), | 176 | 1 | tail: CachePadded::new(Position { | 177 | 1 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 1 | index: AtomicUsize::new(0), | 179 | 1 | }), | 180 | 1 | receivers: SyncWaker::new(), | 181 | 1 | _marker: PhantomData, | 182 | 1 | } | 183 | 1 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::new Line | Count | Source | 170 | 1 | pub(crate) fn new() -> Self { | 171 | 1 | Channel { | 172 | 1 | head: CachePadded::new(Position { | 173 | 1 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 1 | index: AtomicUsize::new(0), | 175 | 1 | }), | 176 | 1 | tail: CachePadded::new(Position { | 177 | 1 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 1 | index: AtomicUsize::new(0), | 179 | 1 | }), | 180 | 1 | receivers: SyncWaker::new(), | 181 | 1 | _marker: PhantomData, | 182 | 1 | } | 183 | 1 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::new Line | Count | Source | 170 | 3 | pub(crate) fn new() -> Self { | 171 | 3 | Channel { | 172 | 3 | head: CachePadded::new(Position { | 173 | 3 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 3 | index: AtomicUsize::new(0), | 175 | 3 | }), | 176 | 3 | tail: CachePadded::new(Position { | 177 | 3 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 3 | index: AtomicUsize::new(0), | 179 | 3 | }), | 180 | 3 | receivers: SyncWaker::new(), | 181 | 3 | _marker: PhantomData, | 182 | 3 | } | 183 | 3 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::new Line | Count | Source | 170 | 10.0k | pub(crate) fn new() -> Self { | 171 | 10.0k | Channel { | 172 | 10.0k | head: CachePadded::new(Position { | 173 | 10.0k | block: AtomicPtr::new(ptr::null_mut()), | 174 | 10.0k | index: AtomicUsize::new(0), | 175 | 10.0k | }), | 176 | 10.0k | tail: CachePadded::new(Position { | 177 | 10.0k | block: AtomicPtr::new(ptr::null_mut()), | 178 | 10.0k | index: AtomicUsize::new(0), | 179 | 10.0k | }), | 180 | 10.0k | receivers: SyncWaker::new(), | 181 | 10.0k | _marker: PhantomData, | 182 | 10.0k | } | 183 | 10.0k | } |
<crossbeam_channel::flavors::list::Channel<list::drops::DropCounter>>::new Line | Count | Source | 170 | 100 | pub(crate) fn new() -> Self { | 171 | 100 | Channel { | 172 | 100 | head: CachePadded::new(Position { | 173 | 100 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 100 | index: AtomicUsize::new(0), | 175 | 100 | }), | 176 | 100 | tail: CachePadded::new(Position { | 177 | 100 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 100 | index: AtomicUsize::new(0), | 179 | 100 | }), | 180 | 100 | receivers: SyncWaker::new(), | 181 | 100 | _marker: PhantomData, | 182 | 100 | } | 183 | 100 | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::new Line | Count | Source | 170 | 1.00k | pub(crate) fn new() -> Self { | 171 | 1.00k | Channel { | 172 | 1.00k | head: CachePadded::new(Position { | 173 | 1.00k | block: AtomicPtr::new(ptr::null_mut()), | 174 | 1.00k | index: AtomicUsize::new(0), | 175 | 1.00k | }), | 176 | 1.00k | tail: CachePadded::new(Position { | 177 | 1.00k | block: AtomicPtr::new(ptr::null_mut()), | 178 | 1.00k | index: AtomicUsize::new(0), | 179 | 1.00k | }), | 180 | 1.00k | receivers: SyncWaker::new(), | 181 | 1.00k | _marker: PhantomData, | 182 | 1.00k | } | 183 | 1.00k | } |
<crossbeam_channel::flavors::list::Channel<()>>::new Line | Count | Source | 170 | 8 | pub(crate) fn new() -> Self { | 171 | 8 | Channel { | 172 | 8 | head: CachePadded::new(Position { | 173 | 8 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 8 | index: AtomicUsize::new(0), | 175 | 8 | }), | 176 | 8 | tail: CachePadded::new(Position { | 177 | 8 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 8 | index: AtomicUsize::new(0), | 179 | 8 | }), | 180 | 8 | receivers: SyncWaker::new(), | 181 | 8 | _marker: PhantomData, | 182 | 8 | } | 183 | 8 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::new Line | Count | Source | 170 | 5 | pub(crate) fn new() -> Self { | 171 | 5 | Channel { | 172 | 5 | head: CachePadded::new(Position { | 173 | 5 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 5 | index: AtomicUsize::new(0), | 175 | 5 | }), | 176 | 5 | tail: CachePadded::new(Position { | 177 | 5 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 5 | index: AtomicUsize::new(0), | 179 | 5 | }), | 180 | 5 | receivers: SyncWaker::new(), | 181 | 5 | _marker: PhantomData, | 182 | 5 | } | 183 | 5 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::new Line | Count | Source | 170 | 2 | pub(crate) fn new() -> Self { | 171 | 2 | Channel { | 172 | 2 | head: CachePadded::new(Position { | 173 | 2 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 2 | index: AtomicUsize::new(0), | 175 | 2 | }), | 176 | 2 | tail: CachePadded::new(Position { | 177 | 2 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 2 | index: AtomicUsize::new(0), | 179 | 2 | }), | 180 | 2 | receivers: SyncWaker::new(), | 181 | 2 | _marker: PhantomData, | 182 | 2 | } | 183 | 2 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::new Line | Count | Source | 170 | 33 | pub(crate) fn new() -> Self { | 171 | 33 | Channel { | 172 | 33 | head: CachePadded::new(Position { | 173 | 33 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 33 | index: AtomicUsize::new(0), | 175 | 33 | }), | 176 | 33 | tail: CachePadded::new(Position { | 177 | 33 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 33 | index: AtomicUsize::new(0), | 179 | 33 | }), | 180 | 33 | receivers: SyncWaker::new(), | 181 | 33 | _marker: PhantomData, | 182 | 33 | } | 183 | 33 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::new Line | Count | Source | 170 | 3 | pub(crate) fn new() -> Self { | 171 | 3 | Channel { | 172 | 3 | head: CachePadded::new(Position { | 173 | 3 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 3 | index: AtomicUsize::new(0), | 175 | 3 | }), | 176 | 3 | tail: CachePadded::new(Position { | 177 | 3 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 3 | index: AtomicUsize::new(0), | 179 | 3 | }), | 180 | 3 | receivers: SyncWaker::new(), | 181 | 3 | _marker: PhantomData, | 182 | 3 | } | 183 | 3 | } |
<crossbeam_channel::flavors::list::Channel<()>>::new Line | Count | Source | 170 | 13 | pub(crate) fn new() -> Self { | 171 | 13 | Channel { | 172 | 13 | head: CachePadded::new(Position { | 173 | 13 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 13 | index: AtomicUsize::new(0), | 175 | 13 | }), | 176 | 13 | tail: CachePadded::new(Position { | 177 | 13 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 13 | index: AtomicUsize::new(0), | 179 | 13 | }), | 180 | 13 | receivers: SyncWaker::new(), | 181 | 13 | _marker: PhantomData, | 182 | 13 | } | 183 | 13 | } |
<crossbeam_channel::flavors::list::Channel<()>>::new Line | Count | Source | 170 | 9 | pub(crate) fn new() -> Self { | 171 | 9 | Channel { | 172 | 9 | head: CachePadded::new(Position { | 173 | 9 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 9 | index: AtomicUsize::new(0), | 175 | 9 | }), | 176 | 9 | tail: CachePadded::new(Position { | 177 | 9 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 9 | index: AtomicUsize::new(0), | 179 | 9 | }), | 180 | 9 | receivers: SyncWaker::new(), | 181 | 9 | _marker: PhantomData, | 182 | 9 | } | 183 | 9 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::new Line | Count | Source | 170 | 3 | pub(crate) fn new() -> Self { | 171 | 3 | Channel { | 172 | 3 | head: CachePadded::new(Position { | 173 | 3 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 3 | index: AtomicUsize::new(0), | 175 | 3 | }), | 176 | 3 | tail: CachePadded::new(Position { | 177 | 3 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 3 | index: AtomicUsize::new(0), | 179 | 3 | }), | 180 | 3 | receivers: SyncWaker::new(), | 181 | 3 | _marker: PhantomData, | 182 | 3 | } | 183 | 3 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::new Line | Count | Source | 170 | 19 | pub(crate) fn new() -> Self { | 171 | 19 | Channel { | 172 | 19 | head: CachePadded::new(Position { | 173 | 19 | block: AtomicPtr::new(ptr::null_mut()), | 174 | 19 | index: AtomicUsize::new(0), | 175 | 19 | }), | 176 | 19 | tail: CachePadded::new(Position { | 177 | 19 | block: AtomicPtr::new(ptr::null_mut()), | 178 | 19 | index: AtomicUsize::new(0), | 179 | 19 | }), | 180 | 19 | receivers: SyncWaker::new(), | 181 | 19 | _marker: PhantomData, | 182 | 19 | } | 183 | 19 | } |
|
184 | | |
185 | | /// Returns a receiver handle to the channel. |
186 | 1.10M | pub(crate) fn receiver(&self) -> Receiver<'_, T> { |
187 | 1.10M | Receiver(self) |
188 | 1.10M | } <crossbeam_channel::flavors::list::Channel<i32>>::receiver Line | Count | Source | 186 | 297k | pub(crate) fn receiver(&self) -> Receiver<'_, T> { | 187 | 297k | Receiver(self) | 188 | 297k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::receiver Line | Count | Source | 186 | 16.5k | pub(crate) fn receiver(&self) -> Receiver<'_, T> { | 187 | 16.5k | Receiver(self) | 188 | 16.5k | } |
<crossbeam_channel::flavors::list::Channel<()>>::receiver Line | Count | Source | 186 | 8.68k | pub(crate) fn receiver(&self) -> Receiver<'_, T> { | 187 | 8.68k | Receiver(self) | 188 | 8.68k | } |
<crossbeam_channel::flavors::list::Channel<()>>::receiver Line | Count | Source | 186 | 7 | pub(crate) fn receiver(&self) -> Receiver<'_, T> { | 187 | 7 | Receiver(self) | 188 | 7 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::receiver Line | Count | Source | 186 | 50.5k | pub(crate) fn receiver(&self) -> Receiver<'_, T> { | 187 | 50.5k | Receiver(self) | 188 | 50.5k | } |
<crossbeam_channel::flavors::list::Channel<()>>::receiver Line | Count | Source | 186 | 19.8k | pub(crate) fn receiver(&self) -> Receiver<'_, T> { | 187 | 19.8k | Receiver(self) | 188 | 19.8k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::receiver Line | Count | Source | 186 | 300k | pub(crate) fn receiver(&self) -> Receiver<'_, T> { | 187 | 300k | Receiver(self) | 188 | 300k | } |
<crossbeam_channel::flavors::list::Channel<()>>::receiver Line | Count | Source | 186 | 15.0k | pub(crate) fn receiver(&self) -> Receiver<'_, T> { | 187 | 15.0k | Receiver(self) | 188 | 15.0k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::receiver Line | Count | Source | 186 | 283k | pub(crate) fn receiver(&self) -> Receiver<'_, T> { | 187 | 283k | Receiver(self) | 188 | 283k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::receiver Line | Count | Source | 186 | 32.7k | pub(crate) fn receiver(&self) -> Receiver<'_, T> { | 187 | 32.7k | Receiver(self) | 188 | 32.7k | } |
<crossbeam_channel::flavors::list::Channel<()>>::receiver Line | Count | Source | 186 | 67.3k | pub(crate) fn receiver(&self) -> Receiver<'_, T> { | 187 | 67.3k | Receiver(self) | 188 | 67.3k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::receiver Line | Count | Source | 186 | 161 | pub(crate) fn receiver(&self) -> Receiver<'_, T> { | 187 | 161 | Receiver(self) | 188 | 161 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::receiver Line | Count | Source | 186 | 15.8k | pub(crate) fn receiver(&self) -> Receiver<'_, T> { | 187 | 15.8k | Receiver(self) | 188 | 15.8k | } |
|
189 | | |
190 | | /// Returns a sender handle to the channel. |
191 | 55.8k | pub(crate) fn sender(&self) -> Sender<'_, T> { |
192 | 55.8k | Sender(self) |
193 | 55.8k | } <crossbeam_channel::flavors::list::Channel<()>>::sender Line | Count | Source | 191 | 4.40k | pub(crate) fn sender(&self) -> Sender<'_, T> { | 192 | 4.40k | Sender(self) | 193 | 4.40k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::sender Line | Count | Source | 191 | 9 | pub(crate) fn sender(&self) -> Sender<'_, T> { | 192 | 9 | Sender(self) | 193 | 9 | } |
<crossbeam_channel::flavors::list::Channel<()>>::sender Line | Count | Source | 191 | 1 | pub(crate) fn sender(&self) -> Sender<'_, T> { | 192 | 1 | Sender(self) | 193 | 1 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::sender Line | Count | Source | 191 | 18 | pub(crate) fn sender(&self) -> Sender<'_, T> { | 192 | 18 | Sender(self) | 193 | 18 | } |
<crossbeam_channel::flavors::list::Channel<()>>::sender Line | Count | Source | 191 | 9.73k | pub(crate) fn sender(&self) -> Sender<'_, T> { | 192 | 9.73k | Sender(self) | 193 | 9.73k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::sender Line | Count | Source | 191 | 9 | pub(crate) fn sender(&self) -> Sender<'_, T> { | 192 | 9 | Sender(self) | 193 | 9 | } |
<crossbeam_channel::flavors::list::Channel<()>>::sender Line | Count | Source | 191 | 41.7k | pub(crate) fn sender(&self) -> Sender<'_, T> { | 192 | 41.7k | Sender(self) | 193 | 41.7k | } |
|
194 | | |
195 | | /// Attempts to reserve a slot for sending a message. |
196 | 2.27M | fn start_send(&self, token: &mut Token) -> bool { |
197 | 2.27M | let backoff = Backoff::new(); |
198 | 2.27M | let mut tail = self.tail.index.load(Ordering::Acquire); |
199 | 2.27M | let mut block = self.tail.block.load(Ordering::Acquire); |
200 | 2.27M | let mut next_block = None; |
201 | | |
202 | 2.30M | loop { |
203 | 2.30M | // Check if the channel is disconnected. |
204 | 2.30M | if tail & MARK_BIT != 0 { |
205 | 19 | token.list.block = ptr::null(); |
206 | 19 | return true; |
207 | 2.30M | } |
208 | 2.30M | |
209 | 2.30M | // Calculate the offset of the index into the block. |
210 | 2.30M | let offset = (tail >> SHIFT) % LAP; |
211 | 2.30M | |
212 | 2.30M | // If we reached the end of the block, wait until the next one is installed. |
213 | 2.30M | if offset == BLOCK_CAP { |
214 | 1.05k | backoff.snooze(); |
215 | 1.05k | tail = self.tail.index.load(Ordering::Acquire); |
216 | 1.05k | block = self.tail.block.load(Ordering::Acquire); |
217 | | continue; |
218 | 2.30M | } |
219 | | |
220 | | // If we're going to have to install the next block, allocate it in advance in order to |
221 | | // make the wait for other threads as short as possible. |
222 | 2.30M | if offset + 1 == BLOCK_CAP && next_block.is_none()76.8k { |
223 | 75.3k | next_block = Some(Box::new(Block::<T>::new())); |
224 | 2.22M | } |
225 | | |
226 | | // If this is the first message to be sent into the channel, we need to allocate the |
227 | | // first block and install it. |
228 | 2.30M | if block.is_null() { |
229 | 11.2k | let new = Box::into_raw(Box::new(Block::<T>::new())); |
230 | 11.2k | |
231 | 11.2k | if self |
232 | 11.2k | .tail |
233 | 11.2k | .block |
234 | 11.2k | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) |
235 | 11.2k | .is_ok() |
236 | 11.2k | { |
237 | 11.2k | self.head.block.store(new, Ordering::Release); |
238 | 11.2k | block = new; |
239 | 11.2k | } else { |
240 | 2 | next_block = unsafe { Some(Box::from_raw(new)) }; |
241 | 2 | tail = self.tail.index.load(Ordering::Acquire); |
242 | 2 | block = self.tail.block.load(Ordering::Acquire); |
243 | | continue; |
244 | | } |
245 | 2.29M | } |
246 | | |
247 | 2.30M | let new_tail = tail + (1 << SHIFT); |
248 | 2.30M | |
249 | 2.30M | // Try advancing the tail forward. |
250 | 2.30M | match self.tail.index.compare_exchange_weak( |
251 | 2.30M | tail, |
252 | 2.30M | new_tail, |
253 | 2.30M | Ordering::SeqCst, |
254 | 2.30M | Ordering::Acquire, |
255 | 2.30M | ) { |
256 | 2.30M | Ok(_) => unsafe { |
257 | | // If we've reached the end of the block, install the next one. |
258 | 2.27M | if offset + 1 == BLOCK_CAP { |
259 | 74.2k | let next_block = Box::into_raw(next_block.unwrap()); |
260 | 74.2k | self.tail.block.store(next_block, Ordering::Release); |
261 | 74.2k | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); |
262 | 74.2k | (*block).next.store(next_block, Ordering::Release); |
263 | 2.22M | } |
264 | | |
265 | 2.30M | token.list.block = block as *const u8; |
266 | 2.30M | token.list.offset = offset; |
267 | 2.30M | return true; |
268 | | }, |
269 | 31.0k | Err(t) => { |
270 | 31.0k | tail = t; |
271 | 31.0k | block = self.tail.block.load(Ordering::Acquire); |
272 | 31.0k | backoff.spin(); |
273 | 31.0k | } |
274 | | } |
275 | | } |
276 | 2.30M | } Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::start_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<zero::drops::DropCounter>>::start_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::start_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::start_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::start_send <crossbeam_channel::flavors::list::Channel<()>>::start_send Line | Count | Source | 196 | 14.3k | fn start_send(&self, token: &mut Token) -> bool { | 197 | 14.3k | let backoff = Backoff::new(); | 198 | 14.3k | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 14.3k | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 14.3k | let mut next_block = None; | 201 | | | 202 | 14.3k | loop { | 203 | 14.3k | // Check if the channel is disconnected. | 204 | 14.3k | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 14.3k | } | 208 | 14.3k | | 209 | 14.3k | // Calculate the offset of the index into the block. | 210 | 14.3k | let offset = (tail >> SHIFT) % LAP; | 211 | 14.3k | | 212 | 14.3k | // If we reached the end of the block, wait until the next one is installed. | 213 | 14.3k | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 14.3k | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 14.3k | if offset + 1 == BLOCK_CAP && next_block.is_none()464 { | 223 | 464 | next_block = Some(Box::new(Block::<T>::new())); | 224 | 13.9k | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 14.3k | if block.is_null() { | 229 | 7 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 7 | | 231 | 7 | if self | 232 | 7 | .tail | 233 | 7 | .block | 234 | 7 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 7 | .is_ok() | 236 | 7 | { | 237 | 7 | self.head.block.store(new, Ordering::Release); | 238 | 7 | block = new; | 239 | 7 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 14.3k | } | 246 | | | 247 | 14.3k | let new_tail = tail + (1 << SHIFT); | 248 | 14.3k | | 249 | 14.3k | // Try advancing the tail forward. | 250 | 14.3k | match self.tail.index.compare_exchange_weak( | 251 | 14.3k | tail, | 252 | 14.3k | new_tail, | 253 | 14.3k | Ordering::SeqCst, | 254 | 14.3k | Ordering::Acquire, | 255 | 14.3k | ) { | 256 | 14.3k | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 14.3k | if offset + 1 == BLOCK_CAP { | 259 | 464 | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 464 | self.tail.block.store(next_block, Ordering::Release); | 261 | 464 | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 464 | (*block).next.store(next_block, Ordering::Release); | 263 | 13.9k | } | 264 | | | 265 | 14.4k | token.list.block = block as *const u8; | 266 | 14.4k | token.list.offset = offset; | 267 | 14.4k | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 14.4k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::start_send Line | Count | Source | 196 | 10.0k | fn start_send(&self, token: &mut Token) -> bool { | 197 | 10.0k | let backoff = Backoff::new(); | 198 | 10.0k | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 10.0k | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 10.0k | let mut next_block = None; | 201 | | | 202 | 10.0k | loop { | 203 | 10.0k | // Check if the channel is disconnected. | 204 | 10.0k | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 10.0k | } | 208 | 10.0k | | 209 | 10.0k | // Calculate the offset of the index into the block. | 210 | 10.0k | let offset = (tail >> SHIFT) % LAP; | 211 | 10.0k | | 212 | 10.0k | // If we reached the end of the block, wait until the next one is installed. | 213 | 10.0k | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 10.0k | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 10.0k | if offset + 1 == BLOCK_CAP && next_block.is_none()322 { | 223 | 322 | next_block = Some(Box::new(Block::<T>::new())); | 224 | 9.68k | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 10.0k | if block.is_null() { | 229 | 3 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 3 | | 231 | 3 | if self | 232 | 3 | .tail | 233 | 3 | .block | 234 | 3 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 3 | .is_ok() | 236 | 3 | { | 237 | 3 | self.head.block.store(new, Ordering::Release); | 238 | 3 | block = new; | 239 | 3 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 9.99k | } | 246 | | | 247 | 10.0k | let new_tail = tail + (1 << SHIFT); | 248 | 10.0k | | 249 | 10.0k | // Try advancing the tail forward. | 250 | 10.0k | match self.tail.index.compare_exchange_weak( | 251 | 10.0k | tail, | 252 | 10.0k | new_tail, | 253 | 10.0k | Ordering::SeqCst, | 254 | 10.0k | Ordering::Acquire, | 255 | 10.0k | ) { | 256 | 10.0k | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 10.0k | if offset + 1 == BLOCK_CAP { | 259 | 322 | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 322 | self.tail.block.store(next_block, Ordering::Release); | 261 | 322 | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 322 | (*block).next.store(next_block, Ordering::Release); | 263 | 9.68k | } | 264 | | | 265 | 10.0k | token.list.block = block as *const u8; | 266 | 10.0k | token.list.offset = offset; | 267 | 10.0k | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 10.0k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::start_send <crossbeam_channel::flavors::list::Channel<i32>>::start_send Line | Count | Source | 196 | 392k | fn start_send(&self, token: &mut Token) -> bool { | 197 | 392k | let backoff = Backoff::new(); | 198 | 392k | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 392k | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 392k | let mut next_block = None; | 201 | | | 202 | 392k | loop { | 203 | 392k | // Check if the channel is disconnected. | 204 | 392k | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 392k | } | 208 | 392k | | 209 | 392k | // Calculate the offset of the index into the block. | 210 | 392k | let offset = (tail >> SHIFT) % LAP; | 211 | 392k | | 212 | 392k | // If we reached the end of the block, wait until the next one is installed. | 213 | 392k | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 392k | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 392k | if offset + 1 == BLOCK_CAP && next_block.is_none()12.8k { | 223 | 12.8k | next_block = Some(Box::new(Block::<T>::new())); | 224 | 382k | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 395k | if block.is_null() { | 229 | 12 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 12 | | 231 | 12 | if self | 232 | 12 | .tail | 233 | 12 | .block | 234 | 12 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 12 | .is_ok() | 236 | 12 | { | 237 | 12 | self.head.block.store(new, Ordering::Release); | 238 | 12 | block = new; | 239 | 12 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 395k | } | 246 | | | 247 | 395k | let new_tail = tail + (1 << SHIFT); | 248 | 395k | | 249 | 395k | // Try advancing the tail forward. | 250 | 395k | match self.tail.index.compare_exchange_weak( | 251 | 395k | tail, | 252 | 395k | new_tail, | 253 | 395k | Ordering::SeqCst, | 254 | 395k | Ordering::Acquire, | 255 | 395k | ) { | 256 | 395k | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 395k | if offset + 1 == BLOCK_CAP { | 259 | 12.8k | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 12.8k | self.tail.block.store(next_block, Ordering::Release); | 261 | 12.8k | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 12.8k | (*block).next.store(next_block, Ordering::Release); | 263 | 385k | } | 264 | | | 265 | 398k | token.list.block = block as *const u8; | 266 | 398k | token.list.offset = offset; | 267 | 398k | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 398k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::start_send Line | Count | Source | 196 | 101k | fn start_send(&self, token: &mut Token) -> bool { | 197 | 101k | let backoff = Backoff::new(); | 198 | 101k | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 101k | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 101k | let mut next_block = None; | 201 | | | 202 | 120k | loop { | 203 | 120k | // Check if the channel is disconnected. | 204 | 120k | if tail & MARK_BIT != 0 { | 205 | 10 | token.list.block = ptr::null(); | 206 | 10 | return true; | 207 | 120k | } | 208 | 120k | | 209 | 120k | // Calculate the offset of the index into the block. | 210 | 120k | let offset = (tail >> SHIFT) % LAP; | 211 | 120k | | 212 | 120k | // If we reached the end of the block, wait until the next one is installed. | 213 | 120k | if offset == BLOCK_CAP { | 214 | 235 | backoff.snooze(); | 215 | 235 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 235 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 120k | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 120k | if offset + 1 == BLOCK_CAP && next_block.is_none()4.60k { | 223 | 3.49k | next_block = Some(Box::new(Block::<T>::new())); | 224 | 114k | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 117k | if block.is_null() { | 229 | 35 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 35 | | 231 | 35 | if self | 232 | 35 | .tail | 233 | 35 | .block | 234 | 35 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 35 | .is_ok() | 236 | 35 | { | 237 | 35 | self.head.block.store(new, Ordering::Release); | 238 | 35 | block = new; | 239 | 35 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 117k | } | 246 | | | 247 | 117k | let new_tail = tail + (1 << SHIFT); | 248 | 117k | | 249 | 117k | // Try advancing the tail forward. | 250 | 117k | match self.tail.index.compare_exchange_weak( | 251 | 117k | tail, | 252 | 117k | new_tail, | 253 | 117k | Ordering::SeqCst, | 254 | 117k | Ordering::Acquire, | 255 | 117k | ) { | 256 | 117k | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 98.7k | if offset + 1 == BLOCK_CAP { | 259 | 3.30k | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 3.30k | self.tail.block.store(next_block, Ordering::Release); | 261 | 3.30k | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 3.30k | (*block).next.store(next_block, Ordering::Release); | 263 | 98.8k | } | 264 | | | 265 | 102k | token.list.block = block as *const u8; | 266 | 102k | token.list.offset = offset; | 267 | 102k | return true; | 268 | | }, | 269 | 18.8k | Err(t) => { | 270 | 18.8k | tail = t; | 271 | 18.8k | block = self.tail.block.load(Ordering::Acquire); | 272 | 18.8k | backoff.spin(); | 273 | 18.8k | } | 274 | | } | 275 | | } | 276 | 102k | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<isize>>>::start_send Line | Count | Source | 196 | 3 | fn start_send(&self, token: &mut Token) -> bool { | 197 | 3 | let backoff = Backoff::new(); | 198 | 3 | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 3 | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 3 | let mut next_block = None; | 201 | | | 202 | 3 | loop { | 203 | 3 | // Check if the channel is disconnected. | 204 | 3 | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 3 | } | 208 | 3 | | 209 | 3 | // Calculate the offset of the index into the block. | 210 | 3 | let offset = (tail >> SHIFT) % LAP; | 211 | 3 | | 212 | 3 | // If we reached the end of the block, wait until the next one is installed. | 213 | 3 | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 3 | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 3 | if offset + 1 == BLOCK_CAP && next_block.is_none()0 { | 223 | 0 | next_block = Some(Box::new(Block::<T>::new())); | 224 | 3 | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 3 | if block.is_null() { | 229 | 3 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 3 | | 231 | 3 | if self | 232 | 3 | .tail | 233 | 3 | .block | 234 | 3 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 3 | .is_ok() | 236 | 3 | { | 237 | 3 | self.head.block.store(new, Ordering::Release); | 238 | 3 | block = new; | 239 | 3 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 0 | } | 246 | | | 247 | 3 | let new_tail = tail + (1 << SHIFT); | 248 | 3 | | 249 | 3 | // Try advancing the tail forward. | 250 | 3 | match self.tail.index.compare_exchange_weak( | 251 | 3 | tail, | 252 | 3 | new_tail, | 253 | 3 | Ordering::SeqCst, | 254 | 3 | Ordering::Acquire, | 255 | 3 | ) { | 256 | 3 | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 3 | if offset + 1 == BLOCK_CAP { | 259 | 0 | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 0 | self.tail.block.store(next_block, Ordering::Release); | 261 | 0 | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 0 | (*block).next.store(next_block, Ordering::Release); | 263 | 3 | } | 264 | | | 265 | 3 | token.list.block = block as *const u8; | 266 | 3 | token.list.offset = offset; | 267 | 3 | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 3 | } |
<crossbeam_channel::flavors::list::Channel<()>>::start_send Line | Count | Source | 196 | 21.6k | fn start_send(&self, token: &mut Token) -> bool { | 197 | 21.6k | let backoff = Backoff::new(); | 198 | 21.6k | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 21.6k | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 21.6k | let mut next_block = None; | 201 | | | 202 | 21.6k | loop { | 203 | 21.6k | // Check if the channel is disconnected. | 204 | 21.6k | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 21.6k | } | 208 | 21.6k | | 209 | 21.6k | // Calculate the offset of the index into the block. | 210 | 21.6k | let offset = (tail >> SHIFT) % LAP; | 211 | 21.6k | | 212 | 21.6k | // If we reached the end of the block, wait until the next one is installed. | 213 | 21.6k | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 21.6k | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 21.6k | if offset + 1 == BLOCK_CAP && next_block.is_none()698 { | 223 | 698 | next_block = Some(Box::new(Block::<T>::new())); | 224 | 20.9k | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 21.6k | if block.is_null() { | 229 | 31 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 31 | | 231 | 31 | if self | 232 | 31 | .tail | 233 | 31 | .block | 234 | 31 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 31 | .is_ok() | 236 | 30 | { | 237 | 30 | self.head.block.store(new, Ordering::Release); | 238 | 30 | block = new; | 239 | 30 | } else { | 240 | 1 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 1 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 1 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 21.6k | } | 246 | | | 247 | 21.6k | let new_tail = tail + (1 << SHIFT); | 248 | 21.6k | | 249 | 21.6k | // Try advancing the tail forward. | 250 | 21.6k | match self.tail.index.compare_exchange_weak( | 251 | 21.6k | tail, | 252 | 21.6k | new_tail, | 253 | 21.6k | Ordering::SeqCst, | 254 | 21.6k | Ordering::Acquire, | 255 | 21.6k | ) { | 256 | 21.6k | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 21.6k | if offset + 1 == BLOCK_CAP { | 259 | 698 | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 698 | self.tail.block.store(next_block, Ordering::Release); | 261 | 698 | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 698 | (*block).next.store(next_block, Ordering::Release); | 263 | 21.0k | } | 264 | | | 265 | 21.7k | token.list.block = block as *const u8; | 266 | 21.7k | token.list.offset = offset; | 267 | 21.7k | return true; | 268 | | }, | 269 | 2 | Err(t) => { | 270 | 2 | tail = t; | 271 | 2 | block = self.tail.block.load(Ordering::Acquire); | 272 | 2 | backoff.spin(); | 273 | 2 | } | 274 | | } | 275 | | } | 276 | 21.7k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::start_send Line | Count | Source | 196 | 202 | fn start_send(&self, token: &mut Token) -> bool { | 197 | 202 | let backoff = Backoff::new(); | 198 | 202 | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 202 | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 202 | let mut next_block = None; | 201 | | | 202 | 202 | loop { | 203 | 202 | // Check if the channel is disconnected. | 204 | 202 | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 202 | } | 208 | 202 | | 209 | 202 | // Calculate the offset of the index into the block. | 210 | 202 | let offset = (tail >> SHIFT) % LAP; | 211 | 202 | | 212 | 202 | // If we reached the end of the block, wait until the next one is installed. | 213 | 202 | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 202 | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 202 | if offset + 1 == BLOCK_CAP && next_block.is_none()6 { | 223 | 6 | next_block = Some(Box::new(Block::<T>::new())); | 224 | 196 | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 202 | if block.is_null() { | 229 | 2 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 2 | | 231 | 2 | if self | 232 | 2 | .tail | 233 | 2 | .block | 234 | 2 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 2 | .is_ok() | 236 | 2 | { | 237 | 2 | self.head.block.store(new, Ordering::Release); | 238 | 2 | block = new; | 239 | 2 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 200 | } | 246 | | | 247 | 202 | let new_tail = tail + (1 << SHIFT); | 248 | 202 | | 249 | 202 | // Try advancing the tail forward. | 250 | 202 | match self.tail.index.compare_exchange_weak( | 251 | 202 | tail, | 252 | 202 | new_tail, | 253 | 202 | Ordering::SeqCst, | 254 | 202 | Ordering::Acquire, | 255 | 202 | ) { | 256 | 202 | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 202 | if offset + 1 == BLOCK_CAP { | 259 | 6 | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 6 | self.tail.block.store(next_block, Ordering::Release); | 261 | 6 | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 6 | (*block).next.store(next_block, Ordering::Release); | 263 | 196 | } | 264 | | | 265 | 202 | token.list.block = block as *const u8; | 266 | 202 | token.list.offset = offset; | 267 | 202 | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 202 | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<i32>>>::start_send Line | Count | Source | 196 | 13 | fn start_send(&self, token: &mut Token) -> bool { | 197 | 13 | let backoff = Backoff::new(); | 198 | 13 | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 13 | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 13 | let mut next_block = None; | 201 | | | 202 | 13 | loop { | 203 | 13 | // Check if the channel is disconnected. | 204 | 13 | if tail & MARK_BIT != 0 { | 205 | 1 | token.list.block = ptr::null(); | 206 | 1 | return true; | 207 | 12 | } | 208 | 12 | | 209 | 12 | // Calculate the offset of the index into the block. | 210 | 12 | let offset = (tail >> SHIFT) % LAP; | 211 | 12 | | 212 | 12 | // If we reached the end of the block, wait until the next one is installed. | 213 | 12 | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 12 | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 12 | if offset + 1 == BLOCK_CAP && next_block.is_none()0 { | 223 | 0 | next_block = Some(Box::new(Block::<T>::new())); | 224 | 12 | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 12 | if block.is_null() { | 229 | 3 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 3 | | 231 | 3 | if self | 232 | 3 | .tail | 233 | 3 | .block | 234 | 3 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 3 | .is_ok() | 236 | 3 | { | 237 | 3 | self.head.block.store(new, Ordering::Release); | 238 | 3 | block = new; | 239 | 3 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 9 | } | 246 | | | 247 | 12 | let new_tail = tail + (1 << SHIFT); | 248 | 12 | | 249 | 12 | // Try advancing the tail forward. | 250 | 12 | match self.tail.index.compare_exchange_weak( | 251 | 12 | tail, | 252 | 12 | new_tail, | 253 | 12 | Ordering::SeqCst, | 254 | 12 | Ordering::Acquire, | 255 | 12 | ) { | 256 | 12 | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 12 | if offset + 1 == BLOCK_CAP { | 259 | 0 | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 0 | self.tail.block.store(next_block, Ordering::Release); | 261 | 0 | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 0 | (*block).next.store(next_block, Ordering::Release); | 263 | 12 | } | 264 | | | 265 | 12 | token.list.block = block as *const u8; | 266 | 12 | token.list.offset = offset; | 267 | 12 | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 13 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::start_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::start_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<array::drops::DropCounter>>::start_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::start_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::start_send <crossbeam_channel::flavors::list::Channel<()>>::start_send Line | Count | Source | 196 | 48 | fn start_send(&self, token: &mut Token) -> bool { | 197 | 48 | let backoff = Backoff::new(); | 198 | 48 | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 48 | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 48 | let mut next_block = None; | 201 | | | 202 | 48 | loop { | 203 | 48 | // Check if the channel is disconnected. | 204 | 48 | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 48 | } | 208 | 48 | | 209 | 48 | // Calculate the offset of the index into the block. | 210 | 48 | let offset = (tail >> SHIFT) % LAP; | 211 | 48 | | 212 | 48 | // If we reached the end of the block, wait until the next one is installed. | 213 | 48 | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 48 | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 48 | if offset + 1 == BLOCK_CAP && next_block.is_none()1 { | 223 | 1 | next_block = Some(Box::new(Block::<T>::new())); | 224 | 47 | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 48 | if block.is_null() { | 229 | 1 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 1 | | 231 | 1 | if self | 232 | 1 | .tail | 233 | 1 | .block | 234 | 1 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 1 | .is_ok() | 236 | 1 | { | 237 | 1 | self.head.block.store(new, Ordering::Release); | 238 | 1 | block = new; | 239 | 1 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 47 | } | 246 | | | 247 | 48 | let new_tail = tail + (1 << SHIFT); | 248 | 48 | | 249 | 48 | // Try advancing the tail forward. | 250 | 48 | match self.tail.index.compare_exchange_weak( | 251 | 48 | tail, | 252 | 48 | new_tail, | 253 | 48 | Ordering::SeqCst, | 254 | 48 | Ordering::Acquire, | 255 | 48 | ) { | 256 | 48 | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 48 | if offset + 1 == BLOCK_CAP { | 259 | 1 | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 1 | self.tail.block.store(next_block, Ordering::Release); | 261 | 1 | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 1 | (*block).next.store(next_block, Ordering::Release); | 263 | 47 | } | 264 | | | 265 | 48 | token.list.block = block as *const u8; | 266 | 48 | token.list.offset = offset; | 267 | 48 | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 48 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::start_send Line | Count | Source | 196 | 15 | fn start_send(&self, token: &mut Token) -> bool { | 197 | 15 | let backoff = Backoff::new(); | 198 | 15 | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 15 | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 15 | let mut next_block = None; | 201 | | | 202 | 16 | loop { | 203 | 16 | // Check if the channel is disconnected. | 204 | 16 | if tail & MARK_BIT != 0 { | 205 | 1 | token.list.block = ptr::null(); | 206 | 1 | return true; | 207 | 15 | } | 208 | 15 | | 209 | 15 | // Calculate the offset of the index into the block. | 210 | 15 | let offset = (tail >> SHIFT) % LAP; | 211 | 15 | | 212 | 15 | // If we reached the end of the block, wait until the next one is installed. | 213 | 15 | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 15 | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 15 | if offset + 1 == BLOCK_CAP && next_block.is_none()0 { | 223 | 0 | next_block = Some(Box::new(Block::<T>::new())); | 224 | 16 | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 16 | if block.is_null() { | 229 | 6 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 6 | | 231 | 6 | if self | 232 | 6 | .tail | 233 | 6 | .block | 234 | 6 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 6 | .is_ok() | 236 | 6 | { | 237 | 6 | self.head.block.store(new, Ordering::Release); | 238 | 6 | block = new; | 239 | 6 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 10 | } | 246 | | | 247 | 16 | let new_tail = tail + (1 << SHIFT); | 248 | 16 | | 249 | 16 | // Try advancing the tail forward. | 250 | 16 | match self.tail.index.compare_exchange_weak( | 251 | 16 | tail, | 252 | 16 | new_tail, | 253 | 16 | Ordering::SeqCst, | 254 | 16 | Ordering::Acquire, | 255 | 16 | ) { | 256 | 16 | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 15 | if offset + 1 == BLOCK_CAP { | 259 | 0 | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 0 | self.tail.block.store(next_block, Ordering::Release); | 261 | 0 | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 0 | (*block).next.store(next_block, Ordering::Release); | 263 | 15 | } | 264 | | | 265 | 15 | token.list.block = block as *const u8; | 266 | 15 | token.list.offset = offset; | 267 | 15 | return true; | 268 | | }, | 269 | 1 | Err(t) => { | 270 | 1 | tail = t; | 271 | 1 | block = self.tail.block.load(Ordering::Acquire); | 272 | 1 | backoff.spin(); | 273 | 1 | } | 274 | | } | 275 | | } | 276 | 16 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::start_send <crossbeam_channel::flavors::list::Channel<i32>>::start_send Line | Count | Source | 196 | 2 | fn start_send(&self, token: &mut Token) -> bool { | 197 | 2 | let backoff = Backoff::new(); | 198 | 2 | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 2 | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 2 | let mut next_block = None; | 201 | | | 202 | 2 | loop { | 203 | 2 | // Check if the channel is disconnected. | 204 | 2 | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 2 | } | 208 | 2 | | 209 | 2 | // Calculate the offset of the index into the block. | 210 | 2 | let offset = (tail >> SHIFT) % LAP; | 211 | 2 | | 212 | 2 | // If we reached the end of the block, wait until the next one is installed. | 213 | 2 | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 2 | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 2 | if offset + 1 == BLOCK_CAP && next_block.is_none()0 { | 223 | 0 | next_block = Some(Box::new(Block::<T>::new())); | 224 | 2 | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 2 | if block.is_null() { | 229 | 1 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 1 | | 231 | 1 | if self | 232 | 1 | .tail | 233 | 1 | .block | 234 | 1 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 1 | .is_ok() | 236 | 1 | { | 237 | 1 | self.head.block.store(new, Ordering::Release); | 238 | 1 | block = new; | 239 | 1 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 1 | } | 246 | | | 247 | 2 | let new_tail = tail + (1 << SHIFT); | 248 | 2 | | 249 | 2 | // Try advancing the tail forward. | 250 | 2 | match self.tail.index.compare_exchange_weak( | 251 | 2 | tail, | 252 | 2 | new_tail, | 253 | 2 | Ordering::SeqCst, | 254 | 2 | Ordering::Acquire, | 255 | 2 | ) { | 256 | 2 | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 2 | if offset + 1 == BLOCK_CAP { | 259 | 0 | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 0 | self.tail.block.store(next_block, Ordering::Release); | 261 | 0 | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 0 | (*block).next.store(next_block, Ordering::Release); | 263 | 2 | } | 264 | | | 265 | 2 | token.list.block = block as *const u8; | 266 | 2 | token.list.offset = offset; | 267 | 2 | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 2 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::start_send <crossbeam_channel::flavors::list::Channel<list::drops::DropCounter>>::start_send Line | Count | Source | 196 | 523k | fn start_send(&self, token: &mut Token) -> bool { | 197 | 523k | let backoff = Backoff::new(); | 198 | 523k | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 523k | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 523k | let mut next_block = None; | 201 | | | 202 | 523k | loop { | 203 | 523k | // Check if the channel is disconnected. | 204 | 523k | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 523k | } | 208 | 523k | | 209 | 523k | // Calculate the offset of the index into the block. | 210 | 523k | let offset = (tail >> SHIFT) % LAP; | 211 | 523k | | 212 | 523k | // If we reached the end of the block, wait until the next one is installed. | 213 | 523k | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 523k | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 523k | if offset + 1 == BLOCK_CAP && next_block.is_none()16.8k { | 223 | 16.8k | next_block = Some(Box::new(Block::<T>::new())); | 224 | 506k | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 523k | if block.is_null() { | 229 | 100 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 100 | | 231 | 100 | if self | 232 | 100 | .tail | 233 | 100 | .block | 234 | 100 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 100 | .is_ok() | 236 | 100 | { | 237 | 100 | self.head.block.store(new, Ordering::Release); | 238 | 100 | block = new; | 239 | 100 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 523k | } | 246 | | | 247 | 523k | let new_tail = tail + (1 << SHIFT); | 248 | 523k | | 249 | 523k | // Try advancing the tail forward. | 250 | 523k | match self.tail.index.compare_exchange_weak( | 251 | 523k | tail, | 252 | 523k | new_tail, | 253 | 523k | Ordering::SeqCst, | 254 | 523k | Ordering::Acquire, | 255 | 523k | ) { | 256 | 523k | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 523k | if offset + 1 == BLOCK_CAP { | 259 | 16.8k | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 16.8k | self.tail.block.store(next_block, Ordering::Release); | 261 | 16.8k | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 16.8k | (*block).next.store(next_block, Ordering::Release); | 263 | 506k | } | 264 | | | 265 | 523k | token.list.block = block as *const u8; | 266 | 523k | token.list.offset = offset; | 267 | 523k | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 523k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::start_send Line | Count | Source | 196 | 112k | fn start_send(&self, token: &mut Token) -> bool { | 197 | 112k | let backoff = Backoff::new(); | 198 | 112k | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 112k | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 112k | let mut next_block = None; | 201 | | | 202 | 116k | loop { | 203 | 116k | // Check if the channel is disconnected. | 204 | 116k | if tail & MARK_BIT != 0 { | 205 | 6 | token.list.block = ptr::null(); | 206 | 6 | return true; | 207 | 116k | } | 208 | 116k | | 209 | 116k | // Calculate the offset of the index into the block. | 210 | 116k | let offset = (tail >> SHIFT) % LAP; | 211 | 116k | | 212 | 116k | // If we reached the end of the block, wait until the next one is installed. | 213 | 116k | if offset == BLOCK_CAP { | 214 | 746 | backoff.snooze(); | 215 | 746 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 746 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 116k | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 116k | if offset + 1 == BLOCK_CAP && next_block.is_none()4.21k { | 223 | 4.19k | next_block = Some(Box::new(Block::<T>::new())); | 224 | 111k | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 115k | if block.is_null() { | 229 | 10.0k | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 10.0k | | 231 | 10.0k | if self | 232 | 10.0k | .tail | 233 | 10.0k | .block | 234 | 10.0k | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 10.0k | .is_ok() | 236 | 10.0k | { | 237 | 10.0k | self.head.block.store(new, Ordering::Release); | 238 | 10.0k | block = new; | 239 | 10.0k | } else { | 240 | 1 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 1 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 1 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 105k | } | 246 | | | 247 | 115k | let new_tail = tail + (1 << SHIFT); | 248 | 115k | | 249 | 115k | // Try advancing the tail forward. | 250 | 115k | match self.tail.index.compare_exchange_weak( | 251 | 115k | tail, | 252 | 115k | new_tail, | 253 | 115k | Ordering::SeqCst, | 254 | 115k | Ordering::Acquire, | 255 | 115k | ) { | 256 | 115k | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 112k | if offset + 1 == BLOCK_CAP { | 259 | 3.32k | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 3.32k | self.tail.block.store(next_block, Ordering::Release); | 261 | 3.32k | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 3.32k | (*block).next.store(next_block, Ordering::Release); | 263 | 109k | } | 264 | | | 265 | 112k | token.list.block = block as *const u8; | 266 | 112k | token.list.offset = offset; | 267 | 112k | return true; | 268 | | }, | 269 | 3.44k | Err(t) => { | 270 | 3.44k | tail = t; | 271 | 3.44k | block = self.tail.block.load(Ordering::Acquire); | 272 | 3.44k | backoff.spin(); | 273 | 3.44k | } | 274 | | } | 275 | | } | 276 | 112k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::start_send Line | Count | Source | 196 | 285k | fn start_send(&self, token: &mut Token) -> bool { | 197 | 285k | let backoff = Backoff::new(); | 198 | 285k | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 285k | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 285k | let mut next_block = None; | 201 | | | 202 | 294k | loop { | 203 | 294k | // Check if the channel is disconnected. | 204 | 294k | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 294k | } | 208 | 294k | | 209 | 294k | // Calculate the offset of the index into the block. | 210 | 294k | let offset = (tail >> SHIFT) % LAP; | 211 | 294k | | 212 | 294k | // If we reached the end of the block, wait until the next one is installed. | 213 | 294k | if offset == BLOCK_CAP { | 214 | 70 | backoff.snooze(); | 215 | 70 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 70 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 294k | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 294k | if offset + 1 == BLOCK_CAP && next_block.is_none()10.1k { | 223 | 9.73k | next_block = Some(Box::new(Block::<T>::new())); | 224 | 273k | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 283k | if block.is_null() { | 229 | 5 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 5 | | 231 | 5 | if self | 232 | 5 | .tail | 233 | 5 | .block | 234 | 5 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 5 | .is_ok() | 236 | 5 | { | 237 | 5 | self.head.block.store(new, Ordering::Release); | 238 | 5 | block = new; | 239 | 5 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 283k | } | 246 | | | 247 | 283k | let new_tail = tail + (1 << SHIFT); | 248 | 283k | | 249 | 283k | // Try advancing the tail forward. | 250 | 283k | match self.tail.index.compare_exchange_weak( | 251 | 283k | tail, | 252 | 283k | new_tail, | 253 | 283k | Ordering::SeqCst, | 254 | 283k | Ordering::Acquire, | 255 | 283k | ) { | 256 | 283k | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 274k | if offset + 1 == BLOCK_CAP { | 259 | 9.67k | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 9.67k | self.tail.block.store(next_block, Ordering::Release); | 261 | 9.67k | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 9.67k | (*block).next.store(next_block, Ordering::Release); | 263 | 279k | } | 264 | | | 265 | 289k | token.list.block = block as *const u8; | 266 | 289k | token.list.offset = offset; | 267 | 289k | return true; | 268 | | }, | 269 | 8.77k | Err(t) => { | 270 | 8.77k | tail = t; | 271 | 8.77k | block = self.tail.block.load(Ordering::Acquire); | 272 | 8.77k | backoff.spin(); | 273 | 8.77k | } | 274 | | } | 275 | | } | 276 | 289k | } |
<crossbeam_channel::flavors::list::Channel<()>>::start_send Line | Count | Source | 196 | 128k | fn start_send(&self, token: &mut Token) -> bool { | 197 | 128k | let backoff = Backoff::new(); | 198 | 128k | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 128k | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 128k | let mut next_block = None; | 201 | | | 202 | 128k | loop { | 203 | 128k | // Check if the channel is disconnected. | 204 | 128k | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 128k | } | 208 | 128k | | 209 | 128k | // Calculate the offset of the index into the block. | 210 | 128k | let offset = (tail >> SHIFT) % LAP; | 211 | 128k | | 212 | 128k | // If we reached the end of the block, wait until the next one is installed. | 213 | 128k | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 128k | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 128k | if offset + 1 == BLOCK_CAP && next_block.is_none()4.18k { | 223 | 4.18k | next_block = Some(Box::new(Block::<T>::new())); | 224 | 123k | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 127k | if block.is_null() { | 229 | 6 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 6 | | 231 | 6 | if self | 232 | 6 | .tail | 233 | 6 | .block | 234 | 6 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 6 | .is_ok() | 236 | 6 | { | 237 | 6 | self.head.block.store(new, Ordering::Release); | 238 | 6 | block = new; | 239 | 6 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 127k | } | 246 | | | 247 | 127k | let new_tail = tail + (1 << SHIFT); | 248 | 127k | | 249 | 127k | // Try advancing the tail forward. | 250 | 127k | match self.tail.index.compare_exchange_weak( | 251 | 127k | tail, | 252 | 127k | new_tail, | 253 | 127k | Ordering::SeqCst, | 254 | 127k | Ordering::Acquire, | 255 | 127k | ) { | 256 | 127k | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 127k | if offset + 1 == BLOCK_CAP { | 259 | 4.19k | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 4.19k | self.tail.block.store(next_block, Ordering::Release); | 261 | 4.19k | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 4.19k | (*block).next.store(next_block, Ordering::Release); | 263 | 125k | } | 264 | | | 265 | 129k | token.list.block = block as *const u8; | 266 | 129k | token.list.offset = offset; | 267 | 129k | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 129k | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::start_send Line | Count | Source | 196 | 1.00k | fn start_send(&self, token: &mut Token) -> bool { | 197 | 1.00k | let backoff = Backoff::new(); | 198 | 1.00k | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 1.00k | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 1.00k | let mut next_block = None; | 201 | | | 202 | 1.00k | loop { | 203 | 1.00k | // Check if the channel is disconnected. | 204 | 1.00k | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 1.00k | } | 208 | 1.00k | | 209 | 1.00k | // Calculate the offset of the index into the block. | 210 | 1.00k | let offset = (tail >> SHIFT) % LAP; | 211 | 1.00k | | 212 | 1.00k | // If we reached the end of the block, wait until the next one is installed. | 213 | 1.00k | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 1.00k | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 1.00k | if offset + 1 == BLOCK_CAP && next_block.is_none()0 { | 223 | 0 | next_block = Some(Box::new(Block::<T>::new())); | 224 | 1.00k | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 1.00k | if block.is_null() { | 229 | 1.00k | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 1.00k | | 231 | 1.00k | if self | 232 | 1.00k | .tail | 233 | 1.00k | .block | 234 | 1.00k | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 1.00k | .is_ok() | 236 | 1.00k | { | 237 | 1.00k | self.head.block.store(new, Ordering::Release); | 238 | 1.00k | block = new; | 239 | 1.00k | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 0 | } | 246 | | | 247 | 1.00k | let new_tail = tail + (1 << SHIFT); | 248 | 1.00k | | 249 | 1.00k | // Try advancing the tail forward. | 250 | 1.00k | match self.tail.index.compare_exchange_weak( | 251 | 1.00k | tail, | 252 | 1.00k | new_tail, | 253 | 1.00k | Ordering::SeqCst, | 254 | 1.00k | Ordering::Acquire, | 255 | 1.00k | ) { | 256 | 1.00k | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 1.00k | if offset + 1 == BLOCK_CAP { | 259 | 0 | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 0 | self.tail.block.store(next_block, Ordering::Release); | 261 | 0 | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 0 | (*block).next.store(next_block, Ordering::Release); | 263 | 1.00k | } | 264 | | | 265 | 1.00k | token.list.block = block as *const u8; | 266 | 1.00k | token.list.offset = offset; | 267 | 1.00k | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 1.00k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any>>>::start_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::start_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u32>>::start_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i64>>::start_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<bool>>::start_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u8>>::start_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::string::String>>::start_send <crossbeam_channel::flavors::list::Channel<i32>>::start_send Line | Count | Source | 196 | 200k | fn start_send(&self, token: &mut Token) -> bool { | 197 | 200k | let backoff = Backoff::new(); | 198 | 200k | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 200k | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 200k | let mut next_block = None; | 201 | | | 202 | 200k | loop { | 203 | 200k | // Check if the channel is disconnected. | 204 | 200k | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 200k | } | 208 | 200k | | 209 | 200k | // Calculate the offset of the index into the block. | 210 | 200k | let offset = (tail >> SHIFT) % LAP; | 211 | 200k | | 212 | 200k | // If we reached the end of the block, wait until the next one is installed. | 213 | 200k | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 200k | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 200k | if offset + 1 == BLOCK_CAP && next_block.is_none()6.45k { | 223 | 6.45k | next_block = Some(Box::new(Block::<T>::new())); | 224 | 193k | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 200k | if block.is_null() { | 229 | 1 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 1 | | 231 | 1 | if self | 232 | 1 | .tail | 233 | 1 | .block | 234 | 1 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 1 | .is_ok() | 236 | 1 | { | 237 | 1 | self.head.block.store(new, Ordering::Release); | 238 | 1 | block = new; | 239 | 1 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 199k | } | 246 | | | 247 | 200k | let new_tail = tail + (1 << SHIFT); | 248 | 200k | | 249 | 200k | // Try advancing the tail forward. | 250 | 200k | match self.tail.index.compare_exchange_weak( | 251 | 200k | tail, | 252 | 200k | new_tail, | 253 | 200k | Ordering::SeqCst, | 254 | 200k | Ordering::Acquire, | 255 | 200k | ) { | 256 | 200k | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 200k | if offset + 1 == BLOCK_CAP { | 259 | 6.45k | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 6.45k | self.tail.block.store(next_block, Ordering::Release); | 261 | 6.45k | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 6.45k | (*block).next.store(next_block, Ordering::Release); | 263 | 193k | } | 264 | | | 265 | 200k | token.list.block = block as *const u8; | 266 | 200k | token.list.offset = offset; | 267 | 200k | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 200k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::start_send Line | Count | Source | 196 | 10.0k | fn start_send(&self, token: &mut Token) -> bool { | 197 | 10.0k | let backoff = Backoff::new(); | 198 | 10.0k | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 10.0k | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 10.0k | let mut next_block = None; | 201 | | | 202 | 10.0k | loop { | 203 | 10.0k | // Check if the channel is disconnected. | 204 | 10.0k | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 10.0k | } | 208 | 10.0k | | 209 | 10.0k | // Calculate the offset of the index into the block. | 210 | 10.0k | let offset = (tail >> SHIFT) % LAP; | 211 | 10.0k | | 212 | 10.0k | // If we reached the end of the block, wait until the next one is installed. | 213 | 10.0k | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 10.0k | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 10.0k | if offset + 1 == BLOCK_CAP && next_block.is_none()322 { | 223 | 322 | next_block = Some(Box::new(Block::<T>::new())); | 224 | 9.68k | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 10.0k | if block.is_null() { | 229 | 3 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 3 | | 231 | 3 | if self | 232 | 3 | .tail | 233 | 3 | .block | 234 | 3 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 3 | .is_ok() | 236 | 3 | { | 237 | 3 | self.head.block.store(new, Ordering::Release); | 238 | 3 | block = new; | 239 | 3 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 9.99k | } | 246 | | | 247 | 10.0k | let new_tail = tail + (1 << SHIFT); | 248 | 10.0k | | 249 | 10.0k | // Try advancing the tail forward. | 250 | 10.0k | match self.tail.index.compare_exchange_weak( | 251 | 10.0k | tail, | 252 | 10.0k | new_tail, | 253 | 10.0k | Ordering::SeqCst, | 254 | 10.0k | Ordering::Acquire, | 255 | 10.0k | ) { | 256 | 10.0k | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 10.0k | if offset + 1 == BLOCK_CAP { | 259 | 322 | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 322 | self.tail.block.store(next_block, Ordering::Release); | 261 | 322 | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 322 | (*block).next.store(next_block, Ordering::Release); | 263 | 9.68k | } | 264 | | | 265 | 10.0k | token.list.block = block as *const u8; | 266 | 10.0k | token.list.offset = offset; | 267 | 10.0k | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 10.0k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::start_send Line | Count | Source | 196 | 386k | fn start_send(&self, token: &mut Token) -> bool { | 197 | 386k | let backoff = Backoff::new(); | 198 | 386k | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 386k | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 386k | let mut next_block = None; | 201 | | | 202 | 386k | loop { | 203 | 386k | // Check if the channel is disconnected. | 204 | 386k | if tail & MARK_BIT != 0 { | 205 | 1 | token.list.block = ptr::null(); | 206 | 1 | return true; | 207 | 386k | } | 208 | 386k | | 209 | 386k | // Calculate the offset of the index into the block. | 210 | 386k | let offset = (tail >> SHIFT) % LAP; | 211 | 386k | | 212 | 386k | // If we reached the end of the block, wait until the next one is installed. | 213 | 386k | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 386k | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 386k | if offset + 1 == BLOCK_CAP && next_block.is_none()12.7k { | 223 | 12.8k | next_block = Some(Box::new(Block::<T>::new())); | 224 | 379k | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 392k | if block.is_null() { | 229 | 17 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 17 | | 231 | 17 | if self | 232 | 17 | .tail | 233 | 17 | .block | 234 | 17 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 17 | .is_ok() | 236 | 17 | { | 237 | 17 | self.head.block.store(new, Ordering::Release); | 238 | 17 | block = new; | 239 | 17 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 392k | } | 246 | | | 247 | 392k | let new_tail = tail + (1 << SHIFT); | 248 | 392k | | 249 | 392k | // Try advancing the tail forward. | 250 | 392k | match self.tail.index.compare_exchange_weak( | 251 | 392k | tail, | 252 | 392k | new_tail, | 253 | 392k | Ordering::SeqCst, | 254 | 392k | Ordering::Acquire, | 255 | 392k | ) { | 256 | 392k | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 392k | if offset + 1 == BLOCK_CAP { | 259 | 12.8k | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 12.8k | self.tail.block.store(next_block, Ordering::Release); | 261 | 12.8k | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 12.8k | (*block).next.store(next_block, Ordering::Release); | 263 | 385k | } | 264 | | | 265 | 398k | token.list.block = block as *const u8; | 266 | 398k | token.list.offset = offset; | 267 | 398k | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 398k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::start_send <crossbeam_channel::flavors::list::Channel<()>>::start_send Line | Count | Source | 196 | 28.1k | fn start_send(&self, token: &mut Token) -> bool { | 197 | 28.1k | let backoff = Backoff::new(); | 198 | 28.1k | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 28.1k | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 28.1k | let mut next_block = None; | 201 | | | 202 | 28.1k | loop { | 203 | 28.1k | // Check if the channel is disconnected. | 204 | 28.1k | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 28.1k | } | 208 | 28.1k | | 209 | 28.1k | // Calculate the offset of the index into the block. | 210 | 28.1k | let offset = (tail >> SHIFT) % LAP; | 211 | 28.1k | | 212 | 28.1k | // If we reached the end of the block, wait until the next one is installed. | 213 | 28.1k | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 28.1k | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 28.1k | if offset + 1 == BLOCK_CAP && next_block.is_none()956 { | 223 | 955 | next_block = Some(Box::new(Block::<T>::new())); | 224 | 27.6k | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 28.6k | if block.is_null() { | 229 | 11 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 11 | | 231 | 11 | if self | 232 | 11 | .tail | 233 | 11 | .block | 234 | 11 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 11 | .is_ok() | 236 | 11 | { | 237 | 11 | self.head.block.store(new, Ordering::Release); | 238 | 11 | block = new; | 239 | 11 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 28.5k | } | 246 | | | 247 | 28.6k | let new_tail = tail + (1 << SHIFT); | 248 | 28.6k | | 249 | 28.6k | // Try advancing the tail forward. | 250 | 28.6k | match self.tail.index.compare_exchange_weak( | 251 | 28.6k | tail, | 252 | 28.6k | new_tail, | 253 | 28.6k | Ordering::SeqCst, | 254 | 28.6k | Ordering::Acquire, | 255 | 28.6k | ) { | 256 | 28.6k | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 28.6k | if offset + 1 == BLOCK_CAP { | 259 | 957 | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 957 | self.tail.block.store(next_block, Ordering::Release); | 261 | 957 | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 957 | (*block).next.store(next_block, Ordering::Release); | 263 | 27.8k | } | 264 | | | 265 | 28.7k | token.list.block = block as *const u8; | 266 | 28.7k | token.list.offset = offset; | 267 | 28.7k | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 28.7k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::start_send Line | Count | Source | 196 | 10.0k | fn start_send(&self, token: &mut Token) -> bool { | 197 | 10.0k | let backoff = Backoff::new(); | 198 | 10.0k | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 10.0k | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 10.0k | let mut next_block = None; | 201 | | | 202 | 10.0k | loop { | 203 | 10.0k | // Check if the channel is disconnected. | 204 | 10.0k | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 10.0k | } | 208 | 10.0k | | 209 | 10.0k | // Calculate the offset of the index into the block. | 210 | 10.0k | let offset = (tail >> SHIFT) % LAP; | 211 | 10.0k | | 212 | 10.0k | // If we reached the end of the block, wait until the next one is installed. | 213 | 10.0k | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 10.0k | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 10.0k | if offset + 1 == BLOCK_CAP && next_block.is_none()322 { | 223 | 322 | next_block = Some(Box::new(Block::<T>::new())); | 224 | 9.68k | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 10.0k | if block.is_null() { | 229 | 3 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 3 | | 231 | 3 | if self | 232 | 3 | .tail | 233 | 3 | .block | 234 | 3 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 3 | .is_ok() | 236 | 3 | { | 237 | 3 | self.head.block.store(new, Ordering::Release); | 238 | 3 | block = new; | 239 | 3 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 9.99k | } | 246 | | | 247 | 10.0k | let new_tail = tail + (1 << SHIFT); | 248 | 10.0k | | 249 | 10.0k | // Try advancing the tail forward. | 250 | 10.0k | match self.tail.index.compare_exchange_weak( | 251 | 10.0k | tail, | 252 | 10.0k | new_tail, | 253 | 10.0k | Ordering::SeqCst, | 254 | 10.0k | Ordering::Acquire, | 255 | 10.0k | ) { | 256 | 10.0k | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 10.0k | if offset + 1 == BLOCK_CAP { | 259 | 322 | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 322 | self.tail.block.store(next_block, Ordering::Release); | 261 | 322 | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 322 | (*block).next.store(next_block, Ordering::Release); | 263 | 9.68k | } | 264 | | | 265 | 10.0k | token.list.block = block as *const u8; | 266 | 10.0k | token.list.offset = offset; | 267 | 10.0k | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 10.0k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::start_send Line | Count | Source | 196 | 14 | fn start_send(&self, token: &mut Token) -> bool { | 197 | 14 | let backoff = Backoff::new(); | 198 | 14 | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 14 | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 14 | let mut next_block = None; | 201 | | | 202 | 14 | loop { | 203 | 14 | // Check if the channel is disconnected. | 204 | 14 | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 14 | } | 208 | 14 | | 209 | 14 | // Calculate the offset of the index into the block. | 210 | 14 | let offset = (tail >> SHIFT) % LAP; | 211 | 14 | | 212 | 14 | // If we reached the end of the block, wait until the next one is installed. | 213 | 14 | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 14 | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 14 | if offset + 1 == BLOCK_CAP && next_block.is_none()0 { | 223 | 0 | next_block = Some(Box::new(Block::<T>::new())); | 224 | 14 | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 14 | if block.is_null() { | 229 | 8 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 8 | | 231 | 8 | if self | 232 | 8 | .tail | 233 | 8 | .block | 234 | 8 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 8 | .is_ok() | 236 | 8 | { | 237 | 8 | self.head.block.store(new, Ordering::Release); | 238 | 8 | block = new; | 239 | 8 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 6 | } | 246 | | | 247 | 14 | let new_tail = tail + (1 << SHIFT); | 248 | 14 | | 249 | 14 | // Try advancing the tail forward. | 250 | 14 | match self.tail.index.compare_exchange_weak( | 251 | 14 | tail, | 252 | 14 | new_tail, | 253 | 14 | Ordering::SeqCst, | 254 | 14 | Ordering::Acquire, | 255 | 14 | ) { | 256 | 14 | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 14 | if offset + 1 == BLOCK_CAP { | 259 | 0 | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 0 | self.tail.block.store(next_block, Ordering::Release); | 261 | 0 | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 0 | (*block).next.store(next_block, Ordering::Release); | 263 | 14 | } | 264 | | | 265 | 14 | token.list.block = block as *const u8; | 266 | 14 | token.list.offset = offset; | 267 | 14 | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 14 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::start_send <crossbeam_channel::flavors::list::Channel<()>>::start_send Line | Count | Source | 196 | 51.6k | fn start_send(&self, token: &mut Token) -> bool { | 197 | 51.6k | let backoff = Backoff::new(); | 198 | 51.6k | let mut tail = self.tail.index.load(Ordering::Acquire); | 199 | 51.6k | let mut block = self.tail.block.load(Ordering::Acquire); | 200 | 51.6k | let mut next_block = None; | 201 | | | 202 | 51.6k | loop { | 203 | 51.6k | // Check if the channel is disconnected. | 204 | 51.6k | if tail & MARK_BIT != 0 { | 205 | 0 | token.list.block = ptr::null(); | 206 | 0 | return true; | 207 | 51.6k | } | 208 | 51.6k | | 209 | 51.6k | // Calculate the offset of the index into the block. | 210 | 51.6k | let offset = (tail >> SHIFT) % LAP; | 211 | 51.6k | | 212 | 51.6k | // If we reached the end of the block, wait until the next one is installed. | 213 | 51.6k | if offset == BLOCK_CAP { | 214 | 0 | backoff.snooze(); | 215 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 216 | 0 | block = self.tail.block.load(Ordering::Acquire); | 217 | | continue; | 218 | 51.6k | } | 219 | | | 220 | | // If we're going to have to install the next block, allocate it in advance in order to | 221 | | // make the wait for other threads as short as possible. | 222 | 51.6k | if offset + 1 == BLOCK_CAP && next_block.is_none()1.66k { | 223 | 1.66k | next_block = Some(Box::new(Block::<T>::new())); | 224 | 50.0k | } | 225 | | | 226 | | // If this is the first message to be sent into the channel, we need to allocate the | 227 | | // first block and install it. | 228 | 51.6k | if block.is_null() { | 229 | 7 | let new = Box::into_raw(Box::new(Block::<T>::new())); | 230 | 7 | | 231 | 7 | if self | 232 | 7 | .tail | 233 | 7 | .block | 234 | 7 | .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) | 235 | 7 | .is_ok() | 236 | 7 | { | 237 | 7 | self.head.block.store(new, Ordering::Release); | 238 | 7 | block = new; | 239 | 7 | } else { | 240 | 0 | next_block = unsafe { Some(Box::from_raw(new)) }; | 241 | 0 | tail = self.tail.index.load(Ordering::Acquire); | 242 | 0 | block = self.tail.block.load(Ordering::Acquire); | 243 | | continue; | 244 | | } | 245 | 51.6k | } | 246 | | | 247 | 51.6k | let new_tail = tail + (1 << SHIFT); | 248 | 51.6k | | 249 | 51.6k | // Try advancing the tail forward. | 250 | 51.6k | match self.tail.index.compare_exchange_weak( | 251 | 51.6k | tail, | 252 | 51.6k | new_tail, | 253 | 51.6k | Ordering::SeqCst, | 254 | 51.6k | Ordering::Acquire, | 255 | 51.6k | ) { | 256 | 51.6k | Ok(_) => unsafe { | 257 | | // If we've reached the end of the block, install the next one. | 258 | 51.6k | if offset + 1 == BLOCK_CAP { | 259 | 1.66k | let next_block = Box::into_raw(next_block.unwrap()); | 260 | 1.66k | self.tail.block.store(next_block, Ordering::Release); | 261 | 1.66k | self.tail.index.fetch_add(1 << SHIFT, Ordering::Release); | 262 | 1.66k | (*block).next.store(next_block, Ordering::Release); | 263 | 50.0k | } | 264 | | | 265 | 51.6k | token.list.block = block as *const u8; | 266 | 51.6k | token.list.offset = offset; | 267 | 51.6k | return true; | 268 | | }, | 269 | 0 | Err(t) => { | 270 | 0 | tail = t; | 271 | 0 | block = self.tail.block.load(Ordering::Acquire); | 272 | 0 | backoff.spin(); | 273 | 0 | } | 274 | | } | 275 | | } | 276 | 51.6k | } |
|
277 | | |
278 | | /// Writes a message into the channel. |
279 | 2.29M | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { |
280 | 2.29M | // If there is no slot, the channel is disconnected. |
281 | 2.29M | if token.list.block.is_null() { |
282 | 19 | return Err(msg); |
283 | 2.29M | } |
284 | 2.29M | |
285 | 2.29M | // Write the message into the slot. |
286 | 2.29M | let block = token.list.block as *mut Block<T>; |
287 | 2.29M | let offset = token.list.offset; |
288 | 2.29M | let slot = (*block).slots.get_unchecked(offset); |
289 | 2.29M | slot.msg.get().write(MaybeUninit::new(msg)); |
290 | 2.29M | slot.state.fetch_or(WRITE, Ordering::Release); |
291 | 2.29M | |
292 | 2.29M | // Wake a sleeping receiver. |
293 | 2.29M | self.receivers.notify(); |
294 | 2.29M | Ok(()) |
295 | 2.29M | } Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::write Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<zero::drops::DropCounter>>::write Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::write Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::write Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::write <crossbeam_channel::flavors::list::Channel<i32>>::write Line | Count | Source | 279 | 398k | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 398k | // If there is no slot, the channel is disconnected. | 281 | 398k | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 398k | } | 284 | 398k | | 285 | 398k | // Write the message into the slot. | 286 | 398k | let block = token.list.block as *mut Block<T>; | 287 | 398k | let offset = token.list.offset; | 288 | 398k | let slot = (*block).slots.get_unchecked(offset); | 289 | 398k | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 398k | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 398k | | 292 | 398k | // Wake a sleeping receiver. | 293 | 398k | self.receivers.notify(); | 294 | 398k | Ok(()) | 295 | 398k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::write Line | Count | Source | 279 | 10.0k | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 10.0k | // If there is no slot, the channel is disconnected. | 281 | 10.0k | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 10.0k | } | 284 | 10.0k | | 285 | 10.0k | // Write the message into the slot. | 286 | 10.0k | let block = token.list.block as *mut Block<T>; | 287 | 10.0k | let offset = token.list.offset; | 288 | 10.0k | let slot = (*block).slots.get_unchecked(offset); | 289 | 10.0k | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 10.0k | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 10.0k | | 292 | 10.0k | // Wake a sleeping receiver. | 293 | 10.0k | self.receivers.notify(); | 294 | 10.0k | Ok(()) | 295 | 10.0k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::write <crossbeam_channel::flavors::list::Channel<()>>::write Line | Count | Source | 279 | 14.2k | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 14.2k | // If there is no slot, the channel is disconnected. | 281 | 14.2k | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 14.2k | } | 284 | 14.2k | | 285 | 14.2k | // Write the message into the slot. | 286 | 14.2k | let block = token.list.block as *mut Block<T>; | 287 | 14.2k | let offset = token.list.offset; | 288 | 14.2k | let slot = (*block).slots.get_unchecked(offset); | 289 | 14.2k | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 14.2k | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 14.2k | | 292 | 14.2k | // Wake a sleeping receiver. | 293 | 14.2k | self.receivers.notify(); | 294 | 14.2k | Ok(()) | 295 | 14.2k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::write Line | Count | Source | 279 | 101k | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 101k | // If there is no slot, the channel is disconnected. | 281 | 101k | if token.list.block.is_null() { | 282 | 10 | return Err(msg); | 283 | 101k | } | 284 | 101k | | 285 | 101k | // Write the message into the slot. | 286 | 101k | let block = token.list.block as *mut Block<T>; | 287 | 101k | let offset = token.list.offset; | 288 | 101k | let slot = (*block).slots.get_unchecked(offset); | 289 | 101k | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 101k | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 101k | | 292 | 101k | // Wake a sleeping receiver. | 293 | 101k | self.receivers.notify(); | 294 | 101k | Ok(()) | 295 | 101k | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<isize>>>::write Line | Count | Source | 279 | 3 | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 3 | // If there is no slot, the channel is disconnected. | 281 | 3 | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 3 | } | 284 | 3 | | 285 | 3 | // Write the message into the slot. | 286 | 3 | let block = token.list.block as *mut Block<T>; | 287 | 3 | let offset = token.list.offset; | 288 | 3 | let slot = (*block).slots.get_unchecked(offset); | 289 | 3 | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 3 | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 3 | | 292 | 3 | // Wake a sleeping receiver. | 293 | 3 | self.receivers.notify(); | 294 | 3 | Ok(()) | 295 | 3 | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<i32>>>::write Line | Count | Source | 279 | 13 | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 13 | // If there is no slot, the channel is disconnected. | 281 | 13 | if token.list.block.is_null() { | 282 | 1 | return Err(msg); | 283 | 12 | } | 284 | 12 | | 285 | 12 | // Write the message into the slot. | 286 | 12 | let block = token.list.block as *mut Block<T>; | 287 | 12 | let offset = token.list.offset; | 288 | 12 | let slot = (*block).slots.get_unchecked(offset); | 289 | 12 | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 12 | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 12 | | 292 | 12 | // Wake a sleeping receiver. | 293 | 12 | self.receivers.notify(); | 294 | 12 | Ok(()) | 295 | 13 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::write Line | Count | Source | 279 | 202 | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 202 | // If there is no slot, the channel is disconnected. | 281 | 202 | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 202 | } | 284 | 202 | | 285 | 202 | // Write the message into the slot. | 286 | 202 | let block = token.list.block as *mut Block<T>; | 287 | 202 | let offset = token.list.offset; | 288 | 202 | let slot = (*block).slots.get_unchecked(offset); | 289 | 202 | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 202 | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 202 | | 292 | 202 | // Wake a sleeping receiver. | 293 | 202 | self.receivers.notify(); | 294 | 202 | Ok(()) | 295 | 202 | } |
<crossbeam_channel::flavors::list::Channel<()>>::write Line | Count | Source | 279 | 21.6k | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 21.6k | // If there is no slot, the channel is disconnected. | 281 | 21.6k | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 21.6k | } | 284 | 21.6k | | 285 | 21.6k | // Write the message into the slot. | 286 | 21.6k | let block = token.list.block as *mut Block<T>; | 287 | 21.6k | let offset = token.list.offset; | 288 | 21.6k | let slot = (*block).slots.get_unchecked(offset); | 289 | 21.6k | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 21.6k | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 21.6k | | 292 | 21.6k | // Wake a sleeping receiver. | 293 | 21.6k | self.receivers.notify(); | 294 | 21.6k | Ok(()) | 295 | 21.6k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<array::drops::DropCounter>>::write Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::write Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::write Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::write Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::write <crossbeam_channel::flavors::list::Channel<()>>::write Line | Count | Source | 279 | 48 | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 48 | // If there is no slot, the channel is disconnected. | 281 | 48 | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 48 | } | 284 | 48 | | 285 | 48 | // Write the message into the slot. | 286 | 48 | let block = token.list.block as *mut Block<T>; | 287 | 48 | let offset = token.list.offset; | 288 | 48 | let slot = (*block).slots.get_unchecked(offset); | 289 | 48 | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 48 | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 48 | | 292 | 48 | // Wake a sleeping receiver. | 293 | 48 | self.receivers.notify(); | 294 | 48 | Ok(()) | 295 | 48 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::write Line | Count | Source | 279 | 17 | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 17 | // If there is no slot, the channel is disconnected. | 281 | 17 | if token.list.block.is_null() { | 282 | 1 | return Err(msg); | 283 | 16 | } | 284 | 16 | | 285 | 16 | // Write the message into the slot. | 286 | 16 | let block = token.list.block as *mut Block<T>; | 287 | 16 | let offset = token.list.offset; | 288 | 16 | let slot = (*block).slots.get_unchecked(offset); | 289 | 16 | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 16 | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 16 | | 292 | 16 | // Wake a sleeping receiver. | 293 | 16 | self.receivers.notify(); | 294 | 16 | Ok(()) | 295 | 17 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::write <crossbeam_channel::flavors::list::Channel<i32>>::write Line | Count | Source | 279 | 2 | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 2 | // If there is no slot, the channel is disconnected. | 281 | 2 | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 2 | } | 284 | 2 | | 285 | 2 | // Write the message into the slot. | 286 | 2 | let block = token.list.block as *mut Block<T>; | 287 | 2 | let offset = token.list.offset; | 288 | 2 | let slot = (*block).slots.get_unchecked(offset); | 289 | 2 | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 2 | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 2 | | 292 | 2 | // Wake a sleeping receiver. | 293 | 2 | self.receivers.notify(); | 294 | 2 | Ok(()) | 295 | 2 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::write <crossbeam_channel::flavors::list::Channel<i32>>::write Line | Count | Source | 279 | 112k | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 112k | // If there is no slot, the channel is disconnected. | 281 | 112k | if token.list.block.is_null() { | 282 | 6 | return Err(msg); | 283 | 112k | } | 284 | 112k | | 285 | 112k | // Write the message into the slot. | 286 | 112k | let block = token.list.block as *mut Block<T>; | 287 | 112k | let offset = token.list.offset; | 288 | 112k | let slot = (*block).slots.get_unchecked(offset); | 289 | 112k | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 112k | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 112k | | 292 | 112k | // Wake a sleeping receiver. | 293 | 112k | self.receivers.notify(); | 294 | 112k | Ok(()) | 295 | 112k | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::write Line | Count | Source | 279 | 1.00k | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 1.00k | // If there is no slot, the channel is disconnected. | 281 | 1.00k | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 1.00k | } | 284 | 1.00k | | 285 | 1.00k | // Write the message into the slot. | 286 | 1.00k | let block = token.list.block as *mut Block<T>; | 287 | 1.00k | let offset = token.list.offset; | 288 | 1.00k | let slot = (*block).slots.get_unchecked(offset); | 289 | 1.00k | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 1.00k | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 1.00k | | 292 | 1.00k | // Wake a sleeping receiver. | 293 | 1.00k | self.receivers.notify(); | 294 | 1.00k | Ok(()) | 295 | 1.00k | } |
<crossbeam_channel::flavors::list::Channel<list::drops::DropCounter>>::write Line | Count | Source | 279 | 523k | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 523k | // If there is no slot, the channel is disconnected. | 281 | 523k | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 523k | } | 284 | 523k | | 285 | 523k | // Write the message into the slot. | 286 | 523k | let block = token.list.block as *mut Block<T>; | 287 | 523k | let offset = token.list.offset; | 288 | 523k | let slot = (*block).slots.get_unchecked(offset); | 289 | 523k | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 523k | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 523k | | 292 | 523k | // Wake a sleeping receiver. | 293 | 523k | self.receivers.notify(); | 294 | 523k | Ok(()) | 295 | 523k | } |
<crossbeam_channel::flavors::list::Channel<()>>::write Line | Count | Source | 279 | 128k | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 128k | // If there is no slot, the channel is disconnected. | 281 | 128k | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 128k | } | 284 | 128k | | 285 | 128k | // Write the message into the slot. | 286 | 128k | let block = token.list.block as *mut Block<T>; | 287 | 128k | let offset = token.list.offset; | 288 | 128k | let slot = (*block).slots.get_unchecked(offset); | 289 | 128k | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 128k | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 128k | | 292 | 128k | // Wake a sleeping receiver. | 293 | 128k | self.receivers.notify(); | 294 | 128k | Ok(()) | 295 | 128k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::write Line | Count | Source | 279 | 286k | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 286k | // If there is no slot, the channel is disconnected. | 281 | 286k | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 286k | } | 284 | 286k | | 285 | 286k | // Write the message into the slot. | 286 | 286k | let block = token.list.block as *mut Block<T>; | 287 | 286k | let offset = token.list.offset; | 288 | 286k | let slot = (*block).slots.get_unchecked(offset); | 289 | 286k | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 286k | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 286k | | 292 | 286k | // Wake a sleeping receiver. | 293 | 286k | self.receivers.notify(); | 294 | 286k | Ok(()) | 295 | 286k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::write <crossbeam_channel::flavors::list::Channel<i32>>::write Line | Count | Source | 279 | 200k | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 200k | // If there is no slot, the channel is disconnected. | 281 | 200k | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 200k | } | 284 | 200k | | 285 | 200k | // Write the message into the slot. | 286 | 200k | let block = token.list.block as *mut Block<T>; | 287 | 200k | let offset = token.list.offset; | 288 | 200k | let slot = (*block).slots.get_unchecked(offset); | 289 | 200k | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 200k | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 200k | | 292 | 200k | // Wake a sleeping receiver. | 293 | 200k | self.receivers.notify(); | 294 | 200k | Ok(()) | 295 | 200k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::string::String>>::write Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u8>>::write Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<bool>>::write Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i64>>::write Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any>>>::write Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u32>>::write <crossbeam_channel::flavors::list::Channel<()>>::write Line | Count | Source | 279 | 28.5k | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 28.5k | // If there is no slot, the channel is disconnected. | 281 | 28.5k | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 28.5k | } | 284 | 28.5k | | 285 | 28.5k | // Write the message into the slot. | 286 | 28.5k | let block = token.list.block as *mut Block<T>; | 287 | 28.5k | let offset = token.list.offset; | 288 | 28.5k | let slot = (*block).slots.get_unchecked(offset); | 289 | 28.5k | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 28.5k | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 28.5k | | 292 | 28.5k | // Wake a sleeping receiver. | 293 | 28.5k | self.receivers.notify(); | 294 | 28.5k | Ok(()) | 295 | 28.5k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::write Line | Count | Source | 279 | 10.0k | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 10.0k | // If there is no slot, the channel is disconnected. | 281 | 10.0k | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 10.0k | } | 284 | 10.0k | | 285 | 10.0k | // Write the message into the slot. | 286 | 10.0k | let block = token.list.block as *mut Block<T>; | 287 | 10.0k | let offset = token.list.offset; | 288 | 10.0k | let slot = (*block).slots.get_unchecked(offset); | 289 | 10.0k | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 10.0k | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 10.0k | | 292 | 10.0k | // Wake a sleeping receiver. | 293 | 10.0k | self.receivers.notify(); | 294 | 10.0k | Ok(()) | 295 | 10.0k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::write <crossbeam_channel::flavors::list::Channel<i32>>::write Line | Count | Source | 279 | 397k | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 397k | // If there is no slot, the channel is disconnected. | 281 | 397k | if token.list.block.is_null() { | 282 | 1 | return Err(msg); | 283 | 397k | } | 284 | 397k | | 285 | 397k | // Write the message into the slot. | 286 | 397k | let block = token.list.block as *mut Block<T>; | 287 | 397k | let offset = token.list.offset; | 288 | 397k | let slot = (*block).slots.get_unchecked(offset); | 289 | 397k | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 397k | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 397k | | 292 | 397k | // Wake a sleeping receiver. | 293 | 397k | self.receivers.notify(); | 294 | 397k | Ok(()) | 295 | 397k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::write <crossbeam_channel::flavors::list::Channel<()>>::write Line | Count | Source | 279 | 51.5k | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 51.5k | // If there is no slot, the channel is disconnected. | 281 | 51.5k | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 51.5k | } | 284 | 51.5k | | 285 | 51.5k | // Write the message into the slot. | 286 | 51.5k | let block = token.list.block as *mut Block<T>; | 287 | 51.5k | let offset = token.list.offset; | 288 | 51.5k | let slot = (*block).slots.get_unchecked(offset); | 289 | 51.5k | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 51.5k | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 51.5k | | 292 | 51.5k | // Wake a sleeping receiver. | 293 | 51.5k | self.receivers.notify(); | 294 | 51.5k | Ok(()) | 295 | 51.5k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::write Line | Count | Source | 279 | 14 | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 14 | // If there is no slot, the channel is disconnected. | 281 | 14 | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 14 | } | 284 | 14 | | 285 | 14 | // Write the message into the slot. | 286 | 14 | let block = token.list.block as *mut Block<T>; | 287 | 14 | let offset = token.list.offset; | 288 | 14 | let slot = (*block).slots.get_unchecked(offset); | 289 | 14 | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 14 | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 14 | | 292 | 14 | // Wake a sleeping receiver. | 293 | 14 | self.receivers.notify(); | 294 | 14 | Ok(()) | 295 | 14 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::write Line | Count | Source | 279 | 10.0k | pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { | 280 | 10.0k | // If there is no slot, the channel is disconnected. | 281 | 10.0k | if token.list.block.is_null() { | 282 | 0 | return Err(msg); | 283 | 10.0k | } | 284 | 10.0k | | 285 | 10.0k | // Write the message into the slot. | 286 | 10.0k | let block = token.list.block as *mut Block<T>; | 287 | 10.0k | let offset = token.list.offset; | 288 | 10.0k | let slot = (*block).slots.get_unchecked(offset); | 289 | 10.0k | slot.msg.get().write(MaybeUninit::new(msg)); | 290 | 10.0k | slot.state.fetch_or(WRITE, Ordering::Release); | 291 | 10.0k | | 292 | 10.0k | // Wake a sleeping receiver. | 293 | 10.0k | self.receivers.notify(); | 294 | 10.0k | Ok(()) | 295 | 10.0k | } |
|
296 | | |
297 | | /// Attempts to reserve a slot for receiving a message. |
298 | 3.08M | fn start_recv(&self, token: &mut Token) -> bool { |
299 | 3.08M | let backoff = Backoff::new(); |
300 | 3.08M | let mut head = self.head.index.load(Ordering::Acquire); |
301 | 3.08M | let mut block = self.head.block.load(Ordering::Acquire); |
302 | | |
303 | 3.18M | loop { |
304 | 3.18M | // Calculate the offset of the index into the block. |
305 | 3.18M | let offset = (head >> SHIFT) % LAP; |
306 | 3.18M | |
307 | 3.18M | // If we reached the end of the block, wait until the next one is installed. |
308 | 3.18M | if offset == BLOCK_CAP { |
309 | 5.45k | backoff.snooze(); |
310 | 5.45k | head = self.head.index.load(Ordering::Acquire); |
311 | 5.45k | block = self.head.block.load(Ordering::Acquire); |
312 | | continue; |
313 | 3.17M | } |
314 | 3.17M | |
315 | 3.17M | let mut new_head = head + (1 << SHIFT); |
316 | 3.17M | |
317 | 3.17M | if new_head & MARK_BIT == 0 { |
318 | 2.24M | atomic::fence(Ordering::SeqCst); |
319 | 2.24M | let tail = self.tail.index.load(Ordering::Relaxed); |
320 | 2.24M | |
321 | 2.24M | // If the tail equals the head, that means the channel is empty. |
322 | 2.24M | if head >> SHIFT == tail >> SHIFT { |
323 | | // If the channel is disconnected... |
324 | 1.00M | if tail & MARK_BIT != 0 { |
325 | | // ...then receive an error. |
326 | 63 | token.list.block = ptr::null(); |
327 | 63 | return true; |
328 | | } else { |
329 | | // Otherwise, the receive operation is not ready. |
330 | 1.00M | return false; |
331 | | } |
332 | 1.23M | } |
333 | 1.23M | |
334 | 1.23M | // If head and tail are not in the same block, set `MARK_BIT` in head. |
335 | 1.23M | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { |
336 | 41.9k | new_head |= MARK_BIT; |
337 | 1.20M | } |
338 | 935k | } |
339 | | |
340 | | // The block can be null here only if the first message is being sent into the channel. |
341 | | // In that case, just wait until it gets initialized. |
342 | 2.18M | if block.is_null() { |
343 | 645 | backoff.snooze(); |
344 | 645 | head = self.head.index.load(Ordering::Acquire); |
345 | 645 | block = self.head.block.load(Ordering::Acquire); |
346 | | continue; |
347 | 2.18M | } |
348 | 2.18M | |
349 | 2.18M | // Try moving the head index forward. |
350 | 2.18M | match self.head.index.compare_exchange_weak( |
351 | 2.18M | head, |
352 | 2.18M | new_head, |
353 | 2.18M | Ordering::SeqCst, |
354 | 2.18M | Ordering::Acquire, |
355 | 2.18M | ) { |
356 | 2.18M | Ok(_) => unsafe { |
357 | | // If we've reached the end of the block, move to the next one. |
358 | 2.09M | if offset + 1 == BLOCK_CAP { |
359 | 18.4E | let next = (*block).wait_next(); |
360 | 18.4E | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); |
361 | 18.4E | if !(*next).next.load(Ordering::Relaxed).is_null() { |
362 | 32.7k | next_index |= MARK_BIT; |
363 | 38.2k | } |
364 | | |
365 | 71.0k | self.head.block.store(next, Ordering::Release); |
366 | 71.0k | self.head.index.store(next_index, Ordering::Release); |
367 | 2.13M | } |
368 | | |
369 | 2.20M | token.list.block = block as *const u8; |
370 | 2.20M | token.list.offset = offset; |
371 | 2.20M | return true; |
372 | | }, |
373 | 89.6k | Err(h) => { |
374 | 89.6k | head = h; |
375 | 89.6k | block = self.head.block.load(Ordering::Acquire); |
376 | 89.6k | backoff.spin(); |
377 | 89.6k | } |
378 | | } |
379 | | } |
380 | 3.21M | } Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<zero::drops::DropCounter>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::start_recv <crossbeam_channel::flavors::list::Channel<usize>>::start_recv Line | Count | Source | 298 | 15.5k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 15.5k | let backoff = Backoff::new(); | 300 | 15.5k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 15.5k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 15.5k | loop { | 304 | 15.5k | // Calculate the offset of the index into the block. | 305 | 15.5k | let offset = (head >> SHIFT) % LAP; | 306 | 15.5k | | 307 | 15.5k | // If we reached the end of the block, wait until the next one is installed. | 308 | 15.5k | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 15.5k | } | 314 | 15.5k | | 315 | 15.5k | let mut new_head = head + (1 << SHIFT); | 316 | 15.5k | | 317 | 15.5k | if new_head & MARK_BIT == 0 { | 318 | 15.5k | atomic::fence(Ordering::SeqCst); | 319 | 15.5k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 15.5k | | 321 | 15.5k | // If the tail equals the head, that means the channel is empty. | 322 | 15.5k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 5.52k | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 0 | token.list.block = ptr::null(); | 327 | 0 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 5.52k | return false; | 331 | | } | 332 | 10.0k | } | 333 | 10.0k | | 334 | 10.0k | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 10.0k | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 270 | new_head |= MARK_BIT; | 337 | 9.73k | } | 338 | 0 | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 10.0k | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 10.0k | } | 348 | 10.0k | | 349 | 10.0k | // Try moving the head index forward. | 350 | 10.0k | match self.head.index.compare_exchange_weak( | 351 | 10.0k | head, | 352 | 10.0k | new_head, | 353 | 10.0k | Ordering::SeqCst, | 354 | 10.0k | Ordering::Acquire, | 355 | 10.0k | ) { | 356 | 10.0k | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 10.0k | if offset + 1 == BLOCK_CAP { | 359 | 322 | let next = (*block).wait_next(); | 360 | 322 | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 322 | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 0 | next_index |= MARK_BIT; | 363 | 322 | } | 364 | | | 365 | 322 | self.head.block.store(next, Ordering::Release); | 366 | 322 | self.head.index.store(next_index, Ordering::Release); | 367 | 9.68k | } | 368 | | | 369 | 10.0k | token.list.block = block as *const u8; | 370 | 10.0k | token.list.offset = offset; | 371 | 10.0k | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 15.5k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::start_recv Line | Count | Source | 298 | 664k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 664k | let backoff = Backoff::new(); | 300 | 664k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 664k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 678k | loop { | 304 | 678k | // Calculate the offset of the index into the block. | 305 | 678k | let offset = (head >> SHIFT) % LAP; | 306 | 678k | | 307 | 678k | // If we reached the end of the block, wait until the next one is installed. | 308 | 678k | if offset == BLOCK_CAP { | 309 | 1.67k | backoff.snooze(); | 310 | 1.67k | head = self.head.index.load(Ordering::Acquire); | 311 | 1.67k | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 677k | } | 314 | 677k | | 315 | 677k | let mut new_head = head + (1 << SHIFT); | 316 | 677k | | 317 | 677k | if new_head & MARK_BIT == 0 { | 318 | 702k | atomic::fence(Ordering::SeqCst); | 319 | 702k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 702k | | 321 | 702k | // If the tail equals the head, that means the channel is empty. | 322 | 702k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 297k | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 7 | token.list.block = ptr::null(); | 327 | 7 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 297k | return false; | 331 | | } | 332 | 404k | } | 333 | 404k | | 334 | 404k | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 404k | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 13.4k | new_head |= MARK_BIT; | 337 | 395k | } | 338 | 18.4E | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 383k | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 383k | } | 348 | 383k | | 349 | 383k | // Try moving the head index forward. | 350 | 383k | match self.head.index.compare_exchange_weak( | 351 | 383k | head, | 352 | 383k | new_head, | 353 | 383k | Ordering::SeqCst, | 354 | 383k | Ordering::Acquire, | 355 | 383k | ) { | 356 | 383k | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 371k | if offset + 1 == BLOCK_CAP { | 359 | 18.4E | let next = (*block).wait_next(); | 360 | 18.4E | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 18.4E | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 0 | next_index |= MARK_BIT; | 363 | 12.8k | } | 364 | | | 365 | 12.8k | self.head.block.store(next, Ordering::Release); | 366 | 12.8k | self.head.index.store(next_index, Ordering::Release); | 367 | 386k | } | 368 | | | 369 | 399k | token.list.block = block as *const u8; | 370 | 399k | token.list.offset = offset; | 371 | 399k | return true; | 372 | | }, | 373 | 12.4k | Err(h) => { | 374 | 12.4k | head = h; | 375 | 12.4k | block = self.head.block.load(Ordering::Acquire); | 376 | 12.4k | backoff.spin(); | 377 | 12.4k | } | 378 | | } | 379 | | } | 380 | 696k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::start_recv <crossbeam_channel::flavors::list::Channel<()>>::start_recv Line | Count | Source | 298 | 8.48k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 8.48k | let backoff = Backoff::new(); | 300 | 8.48k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 8.48k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 8.48k | loop { | 304 | 8.48k | // Calculate the offset of the index into the block. | 305 | 8.48k | let offset = (head >> SHIFT) % LAP; | 306 | 8.48k | | 307 | 8.48k | // If we reached the end of the block, wait until the next one is installed. | 308 | 8.48k | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 8.48k | } | 314 | 8.48k | | 315 | 8.48k | let mut new_head = head + (1 << SHIFT); | 316 | 8.48k | | 317 | 8.48k | if new_head & MARK_BIT == 0 { | 318 | 6.05k | atomic::fence(Ordering::SeqCst); | 319 | 6.05k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 6.05k | | 321 | 6.05k | // If the tail equals the head, that means the channel is empty. | 322 | 6.05k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 1.64k | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 2 | token.list.block = ptr::null(); | 327 | 2 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 1.64k | return false; | 331 | | } | 332 | 4.41k | } | 333 | 4.41k | | 334 | 4.41k | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 4.41k | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 133 | new_head |= MARK_BIT; | 337 | 4.28k | } | 338 | 2.42k | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 6.84k | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 6.84k | } | 348 | 6.84k | | 349 | 6.84k | // Try moving the head index forward. | 350 | 6.84k | match self.head.index.compare_exchange_weak( | 351 | 6.84k | head, | 352 | 6.84k | new_head, | 353 | 6.84k | Ordering::SeqCst, | 354 | 6.84k | Ordering::Acquire, | 355 | 6.84k | ) { | 356 | 6.84k | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 6.84k | if offset + 1 == BLOCK_CAP { | 359 | 199 | let next = (*block).wait_next(); | 360 | 199 | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 199 | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 79 | next_index |= MARK_BIT; | 363 | 142 | } | 364 | | | 365 | 221 | self.head.block.store(next, Ordering::Release); | 366 | 221 | self.head.index.store(next_index, Ordering::Release); | 367 | 6.64k | } | 368 | | | 369 | 6.86k | token.list.block = block as *const u8; | 370 | 6.86k | token.list.offset = offset; | 371 | 6.86k | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 8.50k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::start_recv <crossbeam_channel::flavors::list::Channel<()>>::start_recv Line | Count | Source | 298 | 56.1k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 56.1k | let backoff = Backoff::new(); | 300 | 56.1k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 56.1k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 56.1k | loop { | 304 | 56.1k | // Calculate the offset of the index into the block. | 305 | 56.1k | let offset = (head >> SHIFT) % LAP; | 306 | 56.1k | | 307 | 56.1k | // If we reached the end of the block, wait until the next one is installed. | 308 | 56.1k | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 56.1k | } | 314 | 56.1k | | 315 | 56.1k | let mut new_head = head + (1 << SHIFT); | 316 | 56.1k | | 317 | 56.1k | if new_head & MARK_BIT == 0 { | 318 | 46.1k | atomic::fence(Ordering::SeqCst); | 319 | 46.1k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 46.1k | | 321 | 46.1k | // If the tail equals the head, that means the channel is empty. | 322 | 46.1k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 36.0k | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 4 | token.list.block = ptr::null(); | 327 | 4 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 36.0k | return false; | 331 | | } | 332 | 10.0k | } | 333 | 10.0k | | 334 | 10.0k | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 10.0k | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 299 | new_head |= MARK_BIT; | 337 | 9.77k | } | 338 | 10.0k | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 20.1k | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 20.1k | } | 348 | 20.1k | | 349 | 20.1k | // Try moving the head index forward. | 350 | 20.1k | match self.head.index.compare_exchange_weak( | 351 | 20.1k | head, | 352 | 20.1k | new_head, | 353 | 20.1k | Ordering::SeqCst, | 354 | 20.1k | Ordering::Acquire, | 355 | 20.1k | ) { | 356 | 20.1k | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 20.1k | if offset + 1 == BLOCK_CAP { | 359 | 635 | let next = (*block).wait_next(); | 360 | 635 | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 635 | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 323 | next_index |= MARK_BIT; | 363 | 324 | } | 364 | | | 365 | 647 | self.head.block.store(next, Ordering::Release); | 366 | 647 | self.head.index.store(next_index, Ordering::Release); | 367 | 19.5k | } | 368 | | | 369 | 20.1k | token.list.block = block as *const u8; | 370 | 20.1k | token.list.offset = offset; | 371 | 20.1k | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 56.1k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::start_recv Line | Count | Source | 298 | 3.72k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 3.72k | let backoff = Backoff::new(); | 300 | 3.72k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 3.72k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 3.72k | loop { | 304 | 3.72k | // Calculate the offset of the index into the block. | 305 | 3.72k | let offset = (head >> SHIFT) % LAP; | 306 | 3.72k | | 307 | 3.72k | // If we reached the end of the block, wait until the next one is installed. | 308 | 3.72k | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 3.72k | } | 314 | 3.72k | | 315 | 3.72k | let mut new_head = head + (1 << SHIFT); | 316 | 3.72k | | 317 | 3.72k | if new_head & MARK_BIT == 0 { | 318 | 3.72k | atomic::fence(Ordering::SeqCst); | 319 | 3.72k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 3.72k | | 321 | 3.72k | // If the tail equals the head, that means the channel is empty. | 322 | 3.72k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 3.51k | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 2 | token.list.block = ptr::null(); | 327 | 2 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 3.51k | return false; | 331 | | } | 332 | 201 | } | 333 | 201 | | 334 | 201 | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 201 | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 6 | new_head |= MARK_BIT; | 337 | 195 | } | 338 | 1 | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 202 | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 202 | } | 348 | 202 | | 349 | 202 | // Try moving the head index forward. | 350 | 202 | match self.head.index.compare_exchange_weak( | 351 | 202 | head, | 352 | 202 | new_head, | 353 | 202 | Ordering::SeqCst, | 354 | 202 | Ordering::Acquire, | 355 | 202 | ) { | 356 | 202 | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 202 | if offset + 1 == BLOCK_CAP { | 359 | 6 | let next = (*block).wait_next(); | 360 | 6 | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 6 | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 0 | next_index |= MARK_BIT; | 363 | 6 | } | 364 | | | 365 | 6 | self.head.block.store(next, Ordering::Release); | 366 | 6 | self.head.index.store(next_index, Ordering::Release); | 367 | 196 | } | 368 | | | 369 | 202 | token.list.block = block as *const u8; | 370 | 202 | token.list.offset = offset; | 371 | 202 | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 3.72k | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<i32>>>::start_recv Line | Count | Source | 298 | 29 | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 29 | let backoff = Backoff::new(); | 300 | 29 | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 29 | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 29 | loop { | 304 | 29 | // Calculate the offset of the index into the block. | 305 | 29 | let offset = (head >> SHIFT) % LAP; | 306 | 29 | | 307 | 29 | // If we reached the end of the block, wait until the next one is installed. | 308 | 29 | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 29 | } | 314 | 29 | | 315 | 29 | let mut new_head = head + (1 << SHIFT); | 316 | 29 | | 317 | 29 | if new_head & MARK_BIT == 0 { | 318 | 29 | atomic::fence(Ordering::SeqCst); | 319 | 29 | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 29 | | 321 | 29 | // If the tail equals the head, that means the channel is empty. | 322 | 29 | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 17 | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 1 | token.list.block = ptr::null(); | 327 | 1 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 16 | return false; | 331 | | } | 332 | 12 | } | 333 | 12 | | 334 | 12 | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 12 | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 0 | new_head |= MARK_BIT; | 337 | 12 | } | 338 | 0 | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 12 | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 12 | } | 348 | 12 | | 349 | 12 | // Try moving the head index forward. | 350 | 12 | match self.head.index.compare_exchange_weak( | 351 | 12 | head, | 352 | 12 | new_head, | 353 | 12 | Ordering::SeqCst, | 354 | 12 | Ordering::Acquire, | 355 | 12 | ) { | 356 | 12 | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 12 | if offset + 1 == BLOCK_CAP { | 359 | 0 | let next = (*block).wait_next(); | 360 | 0 | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 0 | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 0 | next_index |= MARK_BIT; | 363 | 0 | } | 364 | | | 365 | 0 | self.head.block.store(next, Ordering::Release); | 366 | 0 | self.head.index.store(next_index, Ordering::Release); | 367 | 12 | } | 368 | | | 369 | 12 | token.list.block = block as *const u8; | 370 | 12 | token.list.offset = offset; | 371 | 12 | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 29 | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<isize>>>::start_recv Line | Count | Source | 298 | 9 | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 9 | let backoff = Backoff::new(); | 300 | 9 | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 9 | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 9 | loop { | 304 | 9 | // Calculate the offset of the index into the block. | 305 | 9 | let offset = (head >> SHIFT) % LAP; | 306 | 9 | | 307 | 9 | // If we reached the end of the block, wait until the next one is installed. | 308 | 9 | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 9 | } | 314 | 9 | | 315 | 9 | let mut new_head = head + (1 << SHIFT); | 316 | 9 | | 317 | 9 | if new_head & MARK_BIT == 0 { | 318 | 9 | atomic::fence(Ordering::SeqCst); | 319 | 9 | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 9 | | 321 | 9 | // If the tail equals the head, that means the channel is empty. | 322 | 9 | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 8 | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 0 | token.list.block = ptr::null(); | 327 | 0 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 8 | return false; | 331 | | } | 332 | 1 | } | 333 | 1 | | 334 | 1 | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 1 | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 0 | new_head |= MARK_BIT; | 337 | 1 | } | 338 | 0 | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 1 | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 1 | } | 348 | 1 | | 349 | 1 | // Try moving the head index forward. | 350 | 1 | match self.head.index.compare_exchange_weak( | 351 | 1 | head, | 352 | 1 | new_head, | 353 | 1 | Ordering::SeqCst, | 354 | 1 | Ordering::Acquire, | 355 | 1 | ) { | 356 | 1 | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 1 | if offset + 1 == BLOCK_CAP { | 359 | 0 | let next = (*block).wait_next(); | 360 | 0 | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 0 | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 0 | next_index |= MARK_BIT; | 363 | 0 | } | 364 | | | 365 | 0 | self.head.block.store(next, Ordering::Release); | 366 | 0 | self.head.index.store(next_index, Ordering::Release); | 367 | 1 | } | 368 | | | 369 | 1 | token.list.block = block as *const u8; | 370 | 1 | token.list.offset = offset; | 371 | 1 | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 9 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::start_recv Line | Count | Source | 298 | 115k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 115k | let backoff = Backoff::new(); | 300 | 115k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 115k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 115k | loop { | 304 | 115k | // Calculate the offset of the index into the block. | 305 | 115k | let offset = (head >> SHIFT) % LAP; | 306 | 115k | | 307 | 115k | // If we reached the end of the block, wait until the next one is installed. | 308 | 115k | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 115k | } | 314 | 115k | | 315 | 115k | let mut new_head = head + (1 << SHIFT); | 316 | 115k | | 317 | 115k | if new_head & MARK_BIT == 0 { | 318 | 28.6k | atomic::fence(Ordering::SeqCst); | 319 | 28.6k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 28.6k | | 321 | 28.6k | // If the tail equals the head, that means the channel is empty. | 322 | 28.6k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 18.3k | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 16 | token.list.block = ptr::null(); | 327 | 16 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 18.3k | return false; | 331 | | } | 332 | 10.2k | } | 333 | 10.2k | | 334 | 10.2k | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 10.2k | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 336 | new_head |= MARK_BIT; | 337 | 9.95k | } | 338 | 87.1k | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 97.4k | if block.is_null() { | 343 | 1 | backoff.snooze(); | 344 | 1 | head = self.head.index.load(Ordering::Acquire); | 345 | 1 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 97.4k | } | 348 | 97.4k | | 349 | 97.4k | // Try moving the head index forward. | 350 | 97.4k | match self.head.index.compare_exchange_weak( | 351 | 97.4k | head, | 352 | 97.4k | new_head, | 353 | 97.4k | Ordering::SeqCst, | 354 | 97.4k | Ordering::Acquire, | 355 | 97.4k | ) { | 356 | 97.4k | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 97.4k | if offset + 1 == BLOCK_CAP { | 359 | 945 | let next = (*block).wait_next(); | 360 | 945 | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 2.88k | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 2.88k | next_index |= MARK_BIT; | 363 | 2.88k | }337 | 364 | | | 365 | 3.22k | self.head.block.store(next, Ordering::Release); | 366 | 3.22k | self.head.index.store(next_index, Ordering::Release); | 367 | 96.4k | } | 368 | | | 369 | 99.6k | token.list.block = block as *const u8; | 370 | 99.6k | token.list.offset = offset; | 371 | 99.6k | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 118k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<array::drops::DropCounter>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::start_recv <crossbeam_channel::flavors::list::Channel<i32>>::start_recv Line | Count | Source | 298 | 81 | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 81 | let backoff = Backoff::new(); | 300 | 81 | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 81 | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 81 | loop { | 304 | 81 | // Calculate the offset of the index into the block. | 305 | 81 | let offset = (head >> SHIFT) % LAP; | 306 | 81 | | 307 | 81 | // If we reached the end of the block, wait until the next one is installed. | 308 | 81 | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 81 | } | 314 | 81 | | 315 | 81 | let mut new_head = head + (1 << SHIFT); | 316 | 81 | | 317 | 81 | if new_head & MARK_BIT == 0 { | 318 | 83 | atomic::fence(Ordering::SeqCst); | 319 | 83 | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 83 | | 321 | 83 | // If the tail equals the head, that means the channel is empty. | 322 | 83 | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 69 | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 2 | token.list.block = ptr::null(); | 327 | 2 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 67 | return false; | 331 | | } | 332 | 14 | } | 333 | 14 | | 334 | 14 | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 14 | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 0 | new_head |= MARK_BIT; | 337 | 15 | } | 338 | 18.4E | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 13 | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 13 | } | 348 | 13 | | 349 | 13 | // Try moving the head index forward. | 350 | 13 | match self.head.index.compare_exchange_weak( | 351 | 13 | head, | 352 | 13 | new_head, | 353 | 13 | Ordering::SeqCst, | 354 | 13 | Ordering::Acquire, | 355 | 13 | ) { | 356 | 13 | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 13 | if offset + 1 == BLOCK_CAP { | 359 | 18.4E | let next = (*block).wait_next(); | 360 | 18.4E | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 18.4E | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 0 | next_index |= MARK_BIT; | 363 | 0 | } | 364 | | | 365 | 0 | self.head.block.store(next, Ordering::Release); | 366 | 0 | self.head.index.store(next_index, Ordering::Release); | 367 | 15 | } | 368 | | | 369 | 15 | token.list.block = block as *const u8; | 370 | 15 | token.list.offset = offset; | 371 | 15 | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 84 | } |
<crossbeam_channel::flavors::list::Channel<()>>::start_recv Line | Count | Source | 298 | 16 | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 16 | let backoff = Backoff::new(); | 300 | 16 | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 16 | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 16 | loop { | 304 | 16 | // Calculate the offset of the index into the block. | 305 | 16 | let offset = (head >> SHIFT) % LAP; | 306 | 16 | | 307 | 16 | // If we reached the end of the block, wait until the next one is installed. | 308 | 16 | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 16 | } | 314 | 16 | | 315 | 16 | let mut new_head = head + (1 << SHIFT); | 316 | 16 | | 317 | 16 | if new_head & MARK_BIT == 0 { | 318 | 13 | atomic::fence(Ordering::SeqCst); | 319 | 13 | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 13 | | 321 | 13 | // If the tail equals the head, that means the channel is empty. | 322 | 13 | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 12 | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 0 | token.list.block = ptr::null(); | 327 | 0 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 12 | return false; | 331 | | } | 332 | 1 | } | 333 | 1 | | 334 | 1 | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 1 | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 1 | new_head |= MARK_BIT; | 337 | 1 | }0 | 338 | 3 | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 4 | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 4 | } | 348 | 4 | | 349 | 4 | // Try moving the head index forward. | 350 | 4 | match self.head.index.compare_exchange_weak( | 351 | 4 | head, | 352 | 4 | new_head, | 353 | 4 | Ordering::SeqCst, | 354 | 4 | Ordering::Acquire, | 355 | 4 | ) { | 356 | 4 | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 4 | if offset + 1 == BLOCK_CAP { | 359 | 0 | let next = (*block).wait_next(); | 360 | 0 | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 0 | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 0 | next_index |= MARK_BIT; | 363 | 0 | } | 364 | | | 365 | 0 | self.head.block.store(next, Ordering::Release); | 366 | 0 | self.head.index.store(next_index, Ordering::Release); | 367 | 4 | } | 368 | | | 369 | 4 | token.list.block = block as *const u8; | 370 | 4 | token.list.offset = offset; | 371 | 4 | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 16 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::start_recv <crossbeam_channel::flavors::list::Channel<i32>>::start_recv Line | Count | Source | 298 | 1 | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 1 | let backoff = Backoff::new(); | 300 | 1 | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 1 | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 1 | loop { | 304 | 1 | // Calculate the offset of the index into the block. | 305 | 1 | let offset = (head >> SHIFT) % LAP; | 306 | 1 | | 307 | 1 | // If we reached the end of the block, wait until the next one is installed. | 308 | 1 | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 1 | } | 314 | 1 | | 315 | 1 | let mut new_head = head + (1 << SHIFT); | 316 | 1 | | 317 | 1 | if new_head & MARK_BIT == 0 { | 318 | 1 | atomic::fence(Ordering::SeqCst); | 319 | 1 | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 1 | | 321 | 1 | // If the tail equals the head, that means the channel is empty. | 322 | 1 | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 0 | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 0 | token.list.block = ptr::null(); | 327 | 0 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 0 | return false; | 331 | | } | 332 | 1 | } | 333 | 1 | | 334 | 1 | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 1 | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 0 | new_head |= MARK_BIT; | 337 | 1 | } | 338 | 0 | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 1 | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 1 | } | 348 | 1 | | 349 | 1 | // Try moving the head index forward. | 350 | 1 | match self.head.index.compare_exchange_weak( | 351 | 1 | head, | 352 | 1 | new_head, | 353 | 1 | Ordering::SeqCst, | 354 | 1 | Ordering::Acquire, | 355 | 1 | ) { | 356 | 1 | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 1 | if offset + 1 == BLOCK_CAP { | 359 | 0 | let next = (*block).wait_next(); | 360 | 0 | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 0 | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 0 | next_index |= MARK_BIT; | 363 | 0 | } | 364 | | | 365 | 0 | self.head.block.store(next, Ordering::Release); | 366 | 0 | self.head.index.store(next_index, Ordering::Release); | 367 | 1 | } | 368 | | | 369 | 1 | token.list.block = block as *const u8; | 370 | 1 | token.list.offset = offset; | 371 | 1 | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 1 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::start_recv <crossbeam_channel::flavors::list::Channel<()>>::start_recv Line | Count | Source | 298 | 165k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 165k | let backoff = Backoff::new(); | 300 | 165k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 165k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 165k | loop { | 304 | 165k | // Calculate the offset of the index into the block. | 305 | 165k | let offset = (head >> SHIFT) % LAP; | 306 | 165k | | 307 | 165k | // If we reached the end of the block, wait until the next one is installed. | 308 | 165k | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 165k | } | 314 | 165k | | 315 | 165k | let mut new_head = head + (1 << SHIFT); | 316 | 165k | | 317 | 165k | if new_head & MARK_BIT == 0 { | 318 | 119k | atomic::fence(Ordering::SeqCst); | 319 | 119k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 119k | | 321 | 119k | // If the tail equals the head, that means the channel is empty. | 322 | 119k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 46.7k | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 2 | token.list.block = ptr::null(); | 327 | 2 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 46.7k | return false; | 331 | | } | 332 | 72.2k | } | 333 | 72.2k | | 334 | 72.2k | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 72.2k | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 1.86k | new_head |= MARK_BIT; | 337 | 70.3k | } | 338 | 46.1k | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 118k | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 118k | } | 348 | 118k | | 349 | 118k | // Try moving the head index forward. | 350 | 118k | match self.head.index.compare_exchange_weak( | 351 | 118k | head, | 352 | 118k | new_head, | 353 | 118k | Ordering::SeqCst, | 354 | 118k | Ordering::Acquire, | 355 | 118k | ) { | 356 | 118k | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 118k | if offset + 1 == BLOCK_CAP { | 359 | 2.52k | let next = (*block).wait_next(); | 360 | 2.52k | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 2.52k | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 1.45k | next_index |= MARK_BIT; | 363 | 2.41k | } | 364 | | | 365 | 3.86k | self.head.block.store(next, Ordering::Release); | 366 | 3.86k | self.head.index.store(next_index, Ordering::Release); | 367 | 115k | } | 368 | | | 369 | 119k | token.list.block = block as *const u8; | 370 | 119k | token.list.offset = offset; | 371 | 119k | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 166k | } |
<crossbeam_channel::flavors::list::Channel<list::drops::DropCounter>>::start_recv Line | Count | Source | 298 | 472k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 472k | let backoff = Backoff::new(); | 300 | 472k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 472k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 472k | loop { | 304 | 472k | // Calculate the offset of the index into the block. | 305 | 472k | let offset = (head >> SHIFT) % LAP; | 306 | 472k | | 307 | 472k | // If we reached the end of the block, wait until the next one is installed. | 308 | 472k | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 472k | } | 314 | 472k | | 315 | 472k | let mut new_head = head + (1 << SHIFT); | 316 | 472k | | 317 | 472k | if new_head & MARK_BIT == 0 { | 318 | 4.27k | atomic::fence(Ordering::SeqCst); | 319 | 4.27k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 4.27k | | 321 | 4.27k | // If the tail equals the head, that means the channel is empty. | 322 | 4.27k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 955 | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 0 | token.list.block = ptr::null(); | 327 | 0 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 955 | return false; | 331 | | } | 332 | 3.32k | } | 333 | 3.32k | | 334 | 3.32k | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 3.32k | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 256 | new_head |= MARK_BIT; | 337 | 3.06k | } | 338 | 468k | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 471k | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 471k | } | 348 | 471k | | 349 | 471k | // Try moving the head index forward. | 350 | 471k | match self.head.index.compare_exchange_weak( | 351 | 471k | head, | 352 | 471k | new_head, | 353 | 471k | Ordering::SeqCst, | 354 | 471k | Ordering::Acquire, | 355 | 471k | ) { | 356 | 471k | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 471k | if offset + 1 == BLOCK_CAP { | 359 | 15.1k | let next = (*block).wait_next(); | 360 | 15.1k | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 15.1k | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 14.9k | next_index |= MARK_BIT; | 363 | 14.9k | }256 | 364 | | | 365 | 15.1k | self.head.block.store(next, Ordering::Release); | 366 | 15.1k | self.head.index.store(next_index, Ordering::Release); | 367 | 456k | } | 368 | | | 369 | 471k | token.list.block = block as *const u8; | 370 | 471k | token.list.offset = offset; | 371 | 471k | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 472k | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::start_recv Line | Count | Source | 298 | 2.50k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 2.50k | let backoff = Backoff::new(); | 300 | 2.50k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 2.50k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 2.52k | loop { | 304 | 2.52k | // Calculate the offset of the index into the block. | 305 | 2.52k | let offset = (head >> SHIFT) % LAP; | 306 | 2.52k | | 307 | 2.52k | // If we reached the end of the block, wait until the next one is installed. | 308 | 2.52k | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 2.52k | } | 314 | 2.52k | | 315 | 2.52k | let mut new_head = head + (1 << SHIFT); | 316 | 2.52k | | 317 | 2.52k | if new_head & MARK_BIT == 0 { | 318 | 2.52k | atomic::fence(Ordering::SeqCst); | 319 | 2.52k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 2.52k | | 321 | 2.52k | // If the tail equals the head, that means the channel is empty. | 322 | 2.52k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 1.50k | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 0 | token.list.block = ptr::null(); | 327 | 0 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 1.50k | return false; | 331 | | } | 332 | 1.02k | } | 333 | 1.02k | | 334 | 1.02k | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 1.02k | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 0 | new_head |= MARK_BIT; | 337 | 1.02k | } | 338 | 0 | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 1.02k | if block.is_null() { | 343 | 24 | backoff.snooze(); | 344 | 24 | head = self.head.index.load(Ordering::Acquire); | 345 | 24 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 1.00k | } | 348 | 1.00k | | 349 | 1.00k | // Try moving the head index forward. | 350 | 1.00k | match self.head.index.compare_exchange_weak( | 351 | 1.00k | head, | 352 | 1.00k | new_head, | 353 | 1.00k | Ordering::SeqCst, | 354 | 1.00k | Ordering::Acquire, | 355 | 1.00k | ) { | 356 | 1.00k | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 1.00k | if offset + 1 == BLOCK_CAP { | 359 | 0 | let next = (*block).wait_next(); | 360 | 0 | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 0 | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 0 | next_index |= MARK_BIT; | 363 | 0 | } | 364 | | | 365 | 0 | self.head.block.store(next, Ordering::Release); | 366 | 0 | self.head.index.store(next_index, Ordering::Release); | 367 | 1.00k | } | 368 | | | 369 | 1.00k | token.list.block = block as *const u8; | 370 | 1.00k | token.list.offset = offset; | 371 | 1.00k | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 2.50k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::start_recv Line | Count | Source | 298 | 206k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 206k | let backoff = Backoff::new(); | 300 | 206k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 206k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 225k | loop { | 304 | 225k | // Calculate the offset of the index into the block. | 305 | 225k | let offset = (head >> SHIFT) % LAP; | 306 | 225k | | 307 | 225k | // If we reached the end of the block, wait until the next one is installed. | 308 | 225k | if offset == BLOCK_CAP { | 309 | 841 | backoff.snooze(); | 310 | 841 | head = self.head.index.load(Ordering::Acquire); | 311 | 841 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 224k | } | 314 | 224k | | 315 | 224k | let mut new_head = head + (1 << SHIFT); | 316 | 224k | | 317 | 224k | if new_head & MARK_BIT == 0 { | 318 | 216k | atomic::fence(Ordering::SeqCst); | 319 | 216k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 216k | | 321 | 216k | // If the tail equals the head, that means the channel is empty. | 322 | 216k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 97.0k | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 4 | token.list.block = ptr::null(); | 327 | 4 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 97.0k | return false; | 331 | | } | 332 | 119k | } | 333 | 119k | | 334 | 119k | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 119k | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 6.26k | new_head |= MARK_BIT; | 337 | 113k | } | 338 | 7.73k | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 127k | if block.is_null() { | 343 | 620 | backoff.snooze(); | 344 | 620 | head = self.head.index.load(Ordering::Acquire); | 345 | 620 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 126k | } | 348 | 126k | | 349 | 126k | // Try moving the head index forward. | 350 | 126k | match self.head.index.compare_exchange_weak( | 351 | 126k | head, | 352 | 126k | new_head, | 353 | 126k | Ordering::SeqCst, | 354 | 126k | Ordering::Acquire, | 355 | 126k | ) { | 356 | 126k | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 109k | if offset + 1 == BLOCK_CAP { | 359 | 3.14k | let next = (*block).wait_next(); | 360 | 3.14k | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 3.14k | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 0 | next_index |= MARK_BIT; | 363 | 3.22k | } | 364 | | | 365 | 3.22k | self.head.block.store(next, Ordering::Release); | 366 | 3.22k | self.head.index.store(next_index, Ordering::Release); | 367 | 106k | } | 368 | | | 369 | 110k | token.list.block = block as *const u8; | 370 | 110k | token.list.offset = offset; | 371 | 110k | return true; | 372 | | }, | 373 | 16.8k | Err(h) => { | 374 | 16.8k | head = h; | 375 | 16.8k | block = self.head.block.load(Ordering::Acquire); | 376 | 16.8k | backoff.spin(); | 377 | 16.8k | } | 378 | | } | 379 | | } | 380 | 207k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::start_recv Line | Count | Source | 298 | 378k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 378k | let backoff = Backoff::new(); | 300 | 378k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 378k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 388k | loop { | 304 | 388k | // Calculate the offset of the index into the block. | 305 | 388k | let offset = (head >> SHIFT) % LAP; | 306 | 388k | | 307 | 388k | // If we reached the end of the block, wait until the next one is installed. | 308 | 388k | if offset == BLOCK_CAP { | 309 | 950 | backoff.snooze(); | 310 | 950 | head = self.head.index.load(Ordering::Acquire); | 311 | 950 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 387k | } | 314 | 387k | | 315 | 387k | let mut new_head = head + (1 << SHIFT); | 316 | 387k | | 317 | 387k | if new_head & MARK_BIT == 0 { | 318 | 201k | atomic::fence(Ordering::SeqCst); | 319 | 201k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 201k | | 321 | 201k | // If the tail equals the head, that means the channel is empty. | 322 | 201k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 100k | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 1 | token.list.block = ptr::null(); | 327 | 1 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 100k | return false; | 331 | | } | 332 | 101k | } | 333 | 101k | | 334 | 101k | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 101k | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 2.76k | new_head |= MARK_BIT; | 337 | 98.4k | } | 338 | 186k | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 287k | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 287k | } | 348 | 287k | | 349 | 287k | // Try moving the head index forward. | 350 | 287k | match self.head.index.compare_exchange_weak( | 351 | 287k | head, | 352 | 287k | new_head, | 353 | 287k | Ordering::SeqCst, | 354 | 287k | Ordering::Acquire, | 355 | 287k | ) { | 356 | 287k | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 277k | if offset + 1 == BLOCK_CAP { | 359 | 18.4E | let next = (*block).wait_next(); | 360 | 18.4E | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 18.4E | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 6.37k | next_index |= MARK_BIT; | 363 | 6.37k | }3.30k | 364 | | | 365 | 9.67k | self.head.block.store(next, Ordering::Release); | 366 | 9.67k | self.head.index.store(next_index, Ordering::Release); | 367 | 283k | } | 368 | | | 369 | 292k | token.list.block = block as *const u8; | 370 | 292k | token.list.offset = offset; | 371 | 292k | return true; | 372 | | }, | 373 | 9.47k | Err(h) => { | 374 | 9.47k | head = h; | 375 | 9.47k | block = self.head.block.load(Ordering::Acquire); | 376 | 9.47k | backoff.spin(); | 377 | 9.47k | } | 378 | | } | 379 | | } | 380 | 393k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u8>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::string::String>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<bool>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::start_recv <crossbeam_channel::flavors::list::Channel<i32>>::start_recv Line | Count | Source | 298 | 300k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 300k | let backoff = Backoff::new(); | 300 | 300k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 300k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 300k | loop { | 304 | 300k | // Calculate the offset of the index into the block. | 305 | 300k | let offset = (head >> SHIFT) % LAP; | 306 | 300k | | 307 | 300k | // If we reached the end of the block, wait until the next one is installed. | 308 | 300k | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 300k | } | 314 | 300k | | 315 | 300k | let mut new_head = head + (1 << SHIFT); | 316 | 300k | | 317 | 300k | if new_head & MARK_BIT == 0 { | 318 | 100k | atomic::fence(Ordering::SeqCst); | 319 | 100k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 100k | | 321 | 100k | // If the tail equals the head, that means the channel is empty. | 322 | 100k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 100k | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 0 | token.list.block = ptr::null(); | 327 | 0 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 100k | return false; | 331 | | } | 332 | 65 | } | 333 | 65 | | 334 | 65 | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 65 | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 3 | new_head |= MARK_BIT; | 337 | 62 | } | 338 | 199k | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 200k | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 200k | } | 348 | 200k | | 349 | 200k | // Try moving the head index forward. | 350 | 200k | match self.head.index.compare_exchange_weak( | 351 | 200k | head, | 352 | 200k | new_head, | 353 | 200k | Ordering::SeqCst, | 354 | 200k | Ordering::Acquire, | 355 | 200k | ) { | 356 | 200k | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 200k | if offset + 1 == BLOCK_CAP { | 359 | 6.45k | let next = (*block).wait_next(); | 360 | 6.45k | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 6.45k | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 6.44k | next_index |= MARK_BIT; | 363 | 6.44k | }3 | 364 | | | 365 | 6.45k | self.head.block.store(next, Ordering::Release); | 366 | 6.45k | self.head.index.store(next_index, Ordering::Release); | 367 | 193k | } | 368 | | | 369 | 200k | token.list.block = block as *const u8; | 370 | 200k | token.list.offset = offset; | 371 | 200k | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 300k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i64>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u32>>::start_recv <crossbeam_channel::flavors::list::Channel<()>>::start_recv Line | Count | Source | 298 | 14.4k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 14.4k | let backoff = Backoff::new(); | 300 | 14.4k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 14.4k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 14.4k | loop { | 304 | 14.4k | // Calculate the offset of the index into the block. | 305 | 14.4k | let offset = (head >> SHIFT) % LAP; | 306 | 14.4k | | 307 | 14.4k | // If we reached the end of the block, wait until the next one is installed. | 308 | 14.4k | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 14.4k | } | 314 | 14.4k | | 315 | 14.4k | let mut new_head = head + (1 << SHIFT); | 316 | 14.4k | | 317 | 14.4k | if new_head & MARK_BIT == 0 { | 318 | 7.05k | atomic::fence(Ordering::SeqCst); | 319 | 7.05k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 7.05k | | 321 | 7.05k | // If the tail equals the head, that means the channel is empty. | 322 | 7.05k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 2.33k | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 2 | token.list.block = ptr::null(); | 327 | 2 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 2.33k | return false; | 331 | | } | 332 | 4.72k | } | 333 | 4.72k | | 334 | 4.72k | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 4.72k | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 141 | new_head |= MARK_BIT; | 337 | 4.58k | } | 338 | 7.35k | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 12.0k | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 12.0k | } | 348 | 12.0k | | 349 | 12.0k | // Try moving the head index forward. | 350 | 12.0k | match self.head.index.compare_exchange_weak( | 351 | 12.0k | head, | 352 | 12.0k | new_head, | 353 | 12.0k | Ordering::SeqCst, | 354 | 12.0k | Ordering::Acquire, | 355 | 12.0k | ) { | 356 | 12.0k | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 12.0k | if offset + 1 == BLOCK_CAP { | 359 | 272 | let next = (*block).wait_next(); | 360 | 272 | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 272 | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 242 | next_index |= MARK_BIT; | 363 | 242 | }152 | 364 | | | 365 | 394 | self.head.block.store(next, Ordering::Release); | 366 | 394 | self.head.index.store(next_index, Ordering::Release); | 367 | 11.8k | } | 368 | | | 369 | 12.2k | token.list.block = block as *const u8; | 370 | 12.2k | token.list.offset = offset; | 371 | 12.2k | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 14.5k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::start_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::start_recv <crossbeam_channel::flavors::list::Channel<i32>>::start_recv Line | Count | Source | 298 | 605k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 605k | let backoff = Backoff::new(); | 300 | 605k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 605k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 658k | loop { | 304 | 658k | // Calculate the offset of the index into the block. | 305 | 658k | let offset = (head >> SHIFT) % LAP; | 306 | 658k | | 307 | 658k | // If we reached the end of the block, wait until the next one is installed. | 308 | 658k | if offset == BLOCK_CAP { | 309 | 1.98k | backoff.snooze(); | 310 | 1.98k | head = self.head.index.load(Ordering::Acquire); | 311 | 1.98k | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 656k | } | 314 | 656k | | 315 | 656k | let mut new_head = head + (1 << SHIFT); | 316 | 656k | | 317 | 656k | if new_head & MARK_BIT == 0 { | 318 | 714k | atomic::fence(Ordering::SeqCst); | 319 | 714k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 714k | | 321 | 714k | // If the tail equals the head, that means the channel is empty. | 322 | 714k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 284k | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 11 | token.list.block = ptr::null(); | 327 | 11 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 284k | return false; | 331 | | } | 332 | 429k | } | 333 | 429k | | 334 | 429k | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 429k | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 14.2k | new_head |= MARK_BIT; | 337 | 426k | } | 338 | 18.4E | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 383k | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 383k | } | 348 | 383k | | 349 | 383k | // Try moving the head index forward. | 350 | 383k | match self.head.index.compare_exchange_weak( | 351 | 383k | head, | 352 | 383k | new_head, | 353 | 383k | Ordering::SeqCst, | 354 | 383k | Ordering::Acquire, | 355 | 383k | ) { | 356 | 383k | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 332k | if offset + 1 == BLOCK_CAP { | 359 | 18.4E | let next = (*block).wait_next(); | 360 | 18.4E | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 18.4E | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 0 | next_index |= MARK_BIT; | 363 | 12.8k | } | 364 | | | 365 | 12.8k | self.head.block.store(next, Ordering::Release); | 366 | 12.8k | self.head.index.store(next_index, Ordering::Release); | 367 | 384k | } | 368 | | | 369 | 397k | token.list.block = block as *const u8; | 370 | 397k | token.list.offset = offset; | 371 | 397k | return true; | 372 | | }, | 373 | 50.8k | Err(h) => { | 374 | 50.8k | head = h; | 375 | 50.8k | block = self.head.block.load(Ordering::Acquire); | 376 | 50.8k | backoff.spin(); | 377 | 50.8k | } | 378 | | } | 379 | | } | 380 | 682k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::start_recv Line | Count | Source | 298 | 21.4k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 21.4k | let backoff = Backoff::new(); | 300 | 21.4k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 21.4k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 21.4k | loop { | 304 | 21.4k | // Calculate the offset of the index into the block. | 305 | 21.4k | let offset = (head >> SHIFT) % LAP; | 306 | 21.4k | | 307 | 21.4k | // If we reached the end of the block, wait until the next one is installed. | 308 | 21.4k | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 21.4k | } | 314 | 21.4k | | 315 | 21.4k | let mut new_head = head + (1 << SHIFT); | 316 | 21.4k | | 317 | 21.4k | if new_head & MARK_BIT == 0 { | 318 | 21.4k | atomic::fence(Ordering::SeqCst); | 319 | 21.4k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 21.4k | | 321 | 21.4k | // If the tail equals the head, that means the channel is empty. | 322 | 21.4k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 11.4k | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 0 | token.list.block = ptr::null(); | 327 | 0 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 11.4k | return false; | 331 | | } | 332 | 10.0k | } | 333 | 10.0k | | 334 | 10.0k | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 10.0k | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 305 | new_head |= MARK_BIT; | 337 | 9.69k | } | 338 | 0 | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 10.0k | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 10.0k | } | 348 | 10.0k | | 349 | 10.0k | // Try moving the head index forward. | 350 | 10.0k | match self.head.index.compare_exchange_weak( | 351 | 10.0k | head, | 352 | 10.0k | new_head, | 353 | 10.0k | Ordering::SeqCst, | 354 | 10.0k | Ordering::Acquire, | 355 | 10.0k | ) { | 356 | 10.0k | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 10.0k | if offset + 1 == BLOCK_CAP { | 359 | 322 | let next = (*block).wait_next(); | 360 | 322 | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 322 | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 0 | next_index |= MARK_BIT; | 363 | 322 | } | 364 | | | 365 | 322 | self.head.block.store(next, Ordering::Release); | 366 | 322 | self.head.index.store(next_index, Ordering::Release); | 367 | 9.68k | } | 368 | | | 369 | 10.0k | token.list.block = block as *const u8; | 370 | 10.0k | token.list.offset = offset; | 371 | 10.0k | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 21.4k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::start_recv <crossbeam_channel::flavors::list::Channel<i32>>::start_recv Line | Count | Source | 298 | 30 | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 30 | let backoff = Backoff::new(); | 300 | 30 | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 30 | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 30 | loop { | 304 | 30 | // Calculate the offset of the index into the block. | 305 | 30 | let offset = (head >> SHIFT) % LAP; | 306 | 30 | | 307 | 30 | // If we reached the end of the block, wait until the next one is installed. | 308 | 30 | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 30 | } | 314 | 30 | | 315 | 30 | let mut new_head = head + (1 << SHIFT); | 316 | 30 | | 317 | 30 | if new_head & MARK_BIT == 0 { | 318 | 30 | atomic::fence(Ordering::SeqCst); | 319 | 30 | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 30 | | 321 | 30 | // If the tail equals the head, that means the channel is empty. | 322 | 30 | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 19 | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 7 | token.list.block = ptr::null(); | 327 | 7 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 12 | return false; | 331 | | } | 332 | 11 | } | 333 | 11 | | 334 | 11 | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 11 | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 0 | new_head |= MARK_BIT; | 337 | 11 | } | 338 | 0 | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 11 | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 11 | } | 348 | 11 | | 349 | 11 | // Try moving the head index forward. | 350 | 11 | match self.head.index.compare_exchange_weak( | 351 | 11 | head, | 352 | 11 | new_head, | 353 | 11 | Ordering::SeqCst, | 354 | 11 | Ordering::Acquire, | 355 | 11 | ) { | 356 | 11 | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 11 | if offset + 1 == BLOCK_CAP { | 359 | 0 | let next = (*block).wait_next(); | 360 | 0 | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 0 | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 0 | next_index |= MARK_BIT; | 363 | 0 | } | 364 | | | 365 | 0 | self.head.block.store(next, Ordering::Release); | 366 | 0 | self.head.index.store(next_index, Ordering::Release); | 367 | 11 | } | 368 | | | 369 | 11 | token.list.block = block as *const u8; | 370 | 11 | token.list.offset = offset; | 371 | 11 | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 30 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::start_recv <crossbeam_channel::flavors::list::Channel<usize>>::start_recv Line | Count | Source | 298 | 10.0k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 10.0k | let backoff = Backoff::new(); | 300 | 10.0k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 10.0k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 10.0k | loop { | 304 | 10.0k | // Calculate the offset of the index into the block. | 305 | 10.0k | let offset = (head >> SHIFT) % LAP; | 306 | 10.0k | | 307 | 10.0k | // If we reached the end of the block, wait until the next one is installed. | 308 | 10.0k | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 10.0k | } | 314 | 10.0k | | 315 | 10.0k | let mut new_head = head + (1 << SHIFT); | 316 | 10.0k | | 317 | 10.0k | if new_head & MARK_BIT == 0 { | 318 | 10.0k | atomic::fence(Ordering::SeqCst); | 319 | 10.0k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 10.0k | | 321 | 10.0k | // If the tail equals the head, that means the channel is empty. | 322 | 10.0k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 0 | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 0 | token.list.block = ptr::null(); | 327 | 0 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 0 | return false; | 331 | | } | 332 | 10.0k | } | 333 | 10.0k | | 334 | 10.0k | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 10.0k | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 321 | new_head |= MARK_BIT; | 337 | 9.68k | } | 338 | 0 | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 10.0k | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 10.0k | } | 348 | 10.0k | | 349 | 10.0k | // Try moving the head index forward. | 350 | 10.0k | match self.head.index.compare_exchange_weak( | 351 | 10.0k | head, | 352 | 10.0k | new_head, | 353 | 10.0k | Ordering::SeqCst, | 354 | 10.0k | Ordering::Acquire, | 355 | 10.0k | ) { | 356 | 10.0k | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 10.0k | if offset + 1 == BLOCK_CAP { | 359 | 322 | let next = (*block).wait_next(); | 360 | 322 | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 322 | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 0 | next_index |= MARK_BIT; | 363 | 322 | } | 364 | | | 365 | 322 | self.head.block.store(next, Ordering::Release); | 366 | 322 | self.head.index.store(next_index, Ordering::Release); | 367 | 9.68k | } | 368 | | | 369 | 10.0k | token.list.block = block as *const u8; | 370 | 10.0k | token.list.offset = offset; | 371 | 10.0k | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 10.0k | } |
<crossbeam_channel::flavors::list::Channel<()>>::start_recv Line | Count | Source | 298 | 44.1k | fn start_recv(&self, token: &mut Token) -> bool { | 299 | 44.1k | let backoff = Backoff::new(); | 300 | 44.1k | let mut head = self.head.index.load(Ordering::Acquire); | 301 | 44.1k | let mut block = self.head.block.load(Ordering::Acquire); | 302 | | | 303 | 44.1k | loop { | 304 | 44.1k | // Calculate the offset of the index into the block. | 305 | 44.1k | let offset = (head >> SHIFT) % LAP; | 306 | 44.1k | | 307 | 44.1k | // If we reached the end of the block, wait until the next one is installed. | 308 | 44.1k | if offset == BLOCK_CAP { | 309 | 0 | backoff.snooze(); | 310 | 0 | head = self.head.index.load(Ordering::Acquire); | 311 | 0 | block = self.head.block.load(Ordering::Acquire); | 312 | | continue; | 313 | 44.1k | } | 314 | 44.1k | | 315 | 44.1k | let mut new_head = head + (1 << SHIFT); | 316 | 44.1k | | 317 | 44.1k | if new_head & MARK_BIT == 0 { | 318 | 41.7k | atomic::fence(Ordering::SeqCst); | 319 | 41.7k | let tail = self.tail.index.load(Ordering::Relaxed); | 320 | 41.7k | | 321 | 41.7k | // If the tail equals the head, that means the channel is empty. | 322 | 41.7k | if head >> SHIFT == tail >> SHIFT { | 323 | | // If the channel is disconnected... | 324 | 9 | if tail & MARK_BIT != 0 { | 325 | | // ...then receive an error. | 326 | 2 | token.list.block = ptr::null(); | 327 | 2 | return true; | 328 | | } else { | 329 | | // Otherwise, the receive operation is not ready. | 330 | 7 | return false; | 331 | | } | 332 | 41.7k | } | 333 | 41.7k | | 334 | 41.7k | // If head and tail are not in the same block, set `MARK_BIT` in head. | 335 | 41.7k | if (head >> SHIFT) / LAP != (tail >> SHIFT) / LAP { | 336 | 1.34k | new_head |= MARK_BIT; | 337 | 40.3k | } | 338 | 2.41k | } | 339 | | | 340 | | // The block can be null here only if the first message is being sent into the channel. | 341 | | // In that case, just wait until it gets initialized. | 342 | 44.1k | if block.is_null() { | 343 | 0 | backoff.snooze(); | 344 | 0 | head = self.head.index.load(Ordering::Acquire); | 345 | 0 | block = self.head.block.load(Ordering::Acquire); | 346 | | continue; | 347 | 44.1k | } | 348 | 44.1k | | 349 | 44.1k | // Try moving the head index forward. | 350 | 44.1k | match self.head.index.compare_exchange_weak( | 351 | 44.1k | head, | 352 | 44.1k | new_head, | 353 | 44.1k | Ordering::SeqCst, | 354 | 44.1k | Ordering::Acquire, | 355 | 44.1k | ) { | 356 | 44.1k | Ok(_) => unsafe { | 357 | | // If we've reached the end of the block, move to the next one. | 358 | 44.1k | if offset + 1 == BLOCK_CAP { | 359 | 1.39k | let next = (*block).wait_next(); | 360 | 1.39k | let mut next_index = (new_head & !MARK_BIT).wrapping_add(1 << SHIFT); | 361 | 1.39k | if !(*next).next.load(Ordering::Relaxed).is_null() { | 362 | 79 | next_index |= MARK_BIT; | 363 | 1.34k | } | 364 | | | 365 | 1.42k | self.head.block.store(next, Ordering::Release); | 366 | 1.42k | self.head.index.store(next_index, Ordering::Release); | 367 | 42.7k | } | 368 | | | 369 | 44.1k | token.list.block = block as *const u8; | 370 | 44.1k | token.list.offset = offset; | 371 | 44.1k | return true; | 372 | | }, | 373 | 0 | Err(h) => { | 374 | 0 | head = h; | 375 | 0 | block = self.head.block.load(Ordering::Acquire); | 376 | 0 | backoff.spin(); | 377 | 0 | } | 378 | | } | 379 | | } | 380 | 44.1k | } |
|
381 | | |
382 | | /// Reads a message from the channel. |
383 | 2.18M | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { |
384 | 2.18M | if token.list.block.is_null() { |
385 | | // The channel is disconnected. |
386 | 63 | return Err(()); |
387 | 2.18M | } |
388 | 2.18M | |
389 | 2.18M | // Read the message. |
390 | 2.18M | let block = token.list.block as *mut Block<T>; |
391 | 2.18M | let offset = token.list.offset; |
392 | 2.18M | let slot = (*block).slots.get_unchecked(offset); |
393 | 2.18M | slot.wait_write(); |
394 | 2.18M | let msg = slot.msg.get().read().assume_init(); |
395 | 2.18M | |
396 | 2.18M | // Destroy the block if we've reached the end, or if another thread wanted to destroy but |
397 | 2.18M | // couldn't because we were busy reading from the slot. |
398 | 2.18M | if offset + 1 == BLOCK_CAP { |
399 | 71.0k | Block::destroy(block, 0); |
400 | 2.11M | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { |
401 | 18 | Block::destroy(block, offset + 1); |
402 | 2.13M | } |
403 | | |
404 | 2.20M | Ok(msg) |
405 | 2.20M | } Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<zero::drops::DropCounter>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::read <crossbeam_channel::flavors::list::Channel<()>>::read Line | Count | Source | 383 | 6.86k | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 6.86k | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 2 | return Err(()); | 387 | 6.86k | } | 388 | 6.86k | | 389 | 6.86k | // Read the message. | 390 | 6.86k | let block = token.list.block as *mut Block<T>; | 391 | 6.86k | let offset = token.list.offset; | 392 | 6.86k | let slot = (*block).slots.get_unchecked(offset); | 393 | 6.86k | slot.wait_write(); | 394 | 6.86k | let msg = slot.msg.get().read().assume_init(); | 395 | 6.86k | | 396 | 6.86k | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 6.86k | // couldn't because we were busy reading from the slot. | 398 | 6.86k | if offset + 1 == BLOCK_CAP { | 399 | 221 | Block::destroy(block, 0); | 400 | 6.64k | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 6.64k | } | 403 | | | 404 | 6.86k | Ok(msg) | 405 | 6.86k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::read Line | Count | Source | 383 | 394k | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 394k | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 7 | return Err(()); | 387 | 394k | } | 388 | 394k | | 389 | 394k | // Read the message. | 390 | 394k | let block = token.list.block as *mut Block<T>; | 391 | 394k | let offset = token.list.offset; | 392 | 394k | let slot = (*block).slots.get_unchecked(offset); | 393 | 394k | slot.wait_write(); | 394 | 394k | let msg = slot.msg.get().read().assume_init(); | 395 | 394k | | 396 | 394k | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 394k | // couldn't because we were busy reading from the slot. | 398 | 394k | if offset + 1 == BLOCK_CAP { | 399 | 12.8k | Block::destroy(block, 0); | 400 | 381k | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 386k | } | 403 | | | 404 | 399k | Ok(msg) | 405 | 399k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::read Line | Count | Source | 383 | 10.0k | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 10.0k | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 0 | return Err(()); | 387 | 10.0k | } | 388 | 10.0k | | 389 | 10.0k | // Read the message. | 390 | 10.0k | let block = token.list.block as *mut Block<T>; | 391 | 10.0k | let offset = token.list.offset; | 392 | 10.0k | let slot = (*block).slots.get_unchecked(offset); | 393 | 10.0k | slot.wait_write(); | 394 | 10.0k | let msg = slot.msg.get().read().assume_init(); | 395 | 10.0k | | 396 | 10.0k | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 10.0k | // couldn't because we were busy reading from the slot. | 398 | 10.0k | if offset + 1 == BLOCK_CAP { | 399 | 322 | Block::destroy(block, 0); | 400 | 9.68k | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 9.68k | } | 403 | | | 404 | 10.0k | Ok(msg) | 405 | 10.0k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::read Line | Count | Source | 383 | 98.7k | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 98.7k | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 16 | return Err(()); | 387 | 98.7k | } | 388 | 98.7k | | 389 | 98.7k | // Read the message. | 390 | 98.7k | let block = token.list.block as *mut Block<T>; | 391 | 98.7k | let offset = token.list.offset; | 392 | 98.7k | let slot = (*block).slots.get_unchecked(offset); | 393 | 98.7k | slot.wait_write(); | 394 | 98.7k | let msg = slot.msg.get().read().assume_init(); | 395 | 98.7k | | 396 | 98.7k | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 98.7k | // couldn't because we were busy reading from the slot. | 398 | 98.7k | if offset + 1 == BLOCK_CAP { | 399 | 3.22k | Block::destroy(block, 0); | 400 | 95.5k | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 96.5k | } | 403 | | | 404 | 99.8k | Ok(msg) | 405 | 99.8k | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<i32>>>::read Line | Count | Source | 383 | 13 | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 13 | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 1 | return Err(()); | 387 | 12 | } | 388 | 12 | | 389 | 12 | // Read the message. | 390 | 12 | let block = token.list.block as *mut Block<T>; | 391 | 12 | let offset = token.list.offset; | 392 | 12 | let slot = (*block).slots.get_unchecked(offset); | 393 | 12 | slot.wait_write(); | 394 | 12 | let msg = slot.msg.get().read().assume_init(); | 395 | 12 | | 396 | 12 | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 12 | // couldn't because we were busy reading from the slot. | 398 | 12 | if offset + 1 == BLOCK_CAP { | 399 | 0 | Block::destroy(block, 0); | 400 | 12 | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 12 | } | 403 | | | 404 | 12 | Ok(msg) | 405 | 13 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::read Line | Count | Source | 383 | 204 | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 204 | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 2 | return Err(()); | 387 | 202 | } | 388 | 202 | | 389 | 202 | // Read the message. | 390 | 202 | let block = token.list.block as *mut Block<T>; | 391 | 202 | let offset = token.list.offset; | 392 | 202 | let slot = (*block).slots.get_unchecked(offset); | 393 | 202 | slot.wait_write(); | 394 | 202 | let msg = slot.msg.get().read().assume_init(); | 395 | 202 | | 396 | 202 | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 202 | // couldn't because we were busy reading from the slot. | 398 | 202 | if offset + 1 == BLOCK_CAP { | 399 | 6 | Block::destroy(block, 0); | 400 | 196 | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 196 | } | 403 | | | 404 | 202 | Ok(msg) | 405 | 204 | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<isize>>>::read Line | Count | Source | 383 | 1 | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 1 | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 0 | return Err(()); | 387 | 1 | } | 388 | 1 | | 389 | 1 | // Read the message. | 390 | 1 | let block = token.list.block as *mut Block<T>; | 391 | 1 | let offset = token.list.offset; | 392 | 1 | let slot = (*block).slots.get_unchecked(offset); | 393 | 1 | slot.wait_write(); | 394 | 1 | let msg = slot.msg.get().read().assume_init(); | 395 | 1 | | 396 | 1 | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 1 | // couldn't because we were busy reading from the slot. | 398 | 1 | if offset + 1 == BLOCK_CAP { | 399 | 0 | Block::destroy(block, 0); | 400 | 1 | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 1 | } | 403 | | | 404 | 1 | Ok(msg) | 405 | 1 | } |
<crossbeam_channel::flavors::list::Channel<()>>::read Line | Count | Source | 383 | 20.1k | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 20.1k | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 4 | return Err(()); | 387 | 20.1k | } | 388 | 20.1k | | 389 | 20.1k | // Read the message. | 390 | 20.1k | let block = token.list.block as *mut Block<T>; | 391 | 20.1k | let offset = token.list.offset; | 392 | 20.1k | let slot = (*block).slots.get_unchecked(offset); | 393 | 20.1k | slot.wait_write(); | 394 | 20.1k | let msg = slot.msg.get().read().assume_init(); | 395 | 20.1k | | 396 | 20.1k | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 20.1k | // couldn't because we were busy reading from the slot. | 398 | 20.1k | if offset + 1 == BLOCK_CAP { | 399 | 647 | Block::destroy(block, 0); | 400 | 19.4k | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 19.4k | } | 403 | | | 404 | 20.1k | Ok(msg) | 405 | 20.1k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<array::drops::DropCounter>>::read <crossbeam_channel::flavors::list::Channel<i32>>::read Line | Count | Source | 383 | 17 | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 17 | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 2 | return Err(()); | 387 | 15 | } | 388 | 15 | | 389 | 15 | // Read the message. | 390 | 15 | let block = token.list.block as *mut Block<T>; | 391 | 15 | let offset = token.list.offset; | 392 | 15 | let slot = (*block).slots.get_unchecked(offset); | 393 | 15 | slot.wait_write(); | 394 | 15 | let msg = slot.msg.get().read().assume_init(); | 395 | 15 | | 396 | 15 | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 15 | // couldn't because we were busy reading from the slot. | 398 | 15 | if offset + 1 == BLOCK_CAP { | 399 | 0 | Block::destroy(block, 0); | 400 | 15 | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 15 | } | 403 | | | 404 | 15 | Ok(msg) | 405 | 17 | } |
<crossbeam_channel::flavors::list::Channel<()>>::read Line | Count | Source | 383 | 4 | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 4 | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 0 | return Err(()); | 387 | 4 | } | 388 | 4 | | 389 | 4 | // Read the message. | 390 | 4 | let block = token.list.block as *mut Block<T>; | 391 | 4 | let offset = token.list.offset; | 392 | 4 | let slot = (*block).slots.get_unchecked(offset); | 393 | 4 | slot.wait_write(); | 394 | 4 | let msg = slot.msg.get().read().assume_init(); | 395 | 4 | | 396 | 4 | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 4 | // couldn't because we were busy reading from the slot. | 398 | 4 | if offset + 1 == BLOCK_CAP { | 399 | 0 | Block::destroy(block, 0); | 400 | 4 | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 4 | } | 403 | | | 404 | 4 | Ok(msg) | 405 | 4 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::read <crossbeam_channel::flavors::list::Channel<i32>>::read Line | Count | Source | 383 | 1 | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 1 | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 0 | return Err(()); | 387 | 1 | } | 388 | 1 | | 389 | 1 | // Read the message. | 390 | 1 | let block = token.list.block as *mut Block<T>; | 391 | 1 | let offset = token.list.offset; | 392 | 1 | let slot = (*block).slots.get_unchecked(offset); | 393 | 1 | slot.wait_write(); | 394 | 1 | let msg = slot.msg.get().read().assume_init(); | 395 | 1 | | 396 | 1 | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 1 | // couldn't because we were busy reading from the slot. | 398 | 1 | if offset + 1 == BLOCK_CAP { | 399 | 0 | Block::destroy(block, 0); | 400 | 1 | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 1 | } | 403 | | | 404 | 1 | Ok(msg) | 405 | 1 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::read <crossbeam_channel::flavors::list::Channel<()>>::read Line | Count | Source | 383 | 118k | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 118k | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 2 | return Err(()); | 387 | 118k | } | 388 | 118k | | 389 | 118k | // Read the message. | 390 | 118k | let block = token.list.block as *mut Block<T>; | 391 | 118k | let offset = token.list.offset; | 392 | 118k | let slot = (*block).slots.get_unchecked(offset); | 393 | 118k | slot.wait_write(); | 394 | 118k | let msg = slot.msg.get().read().assume_init(); | 395 | 118k | | 396 | 118k | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 118k | // couldn't because we were busy reading from the slot. | 398 | 118k | if offset + 1 == BLOCK_CAP { | 399 | 3.86k | Block::destroy(block, 0); | 400 | 114k | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 115k | } | 403 | | | 404 | 119k | Ok(msg) | 405 | 119k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::read Line | Count | Source | 383 | 109k | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 109k | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 4 | return Err(()); | 387 | 109k | } | 388 | 109k | | 389 | 109k | // Read the message. | 390 | 109k | let block = token.list.block as *mut Block<T>; | 391 | 109k | let offset = token.list.offset; | 392 | 109k | let slot = (*block).slots.get_unchecked(offset); | 393 | 109k | slot.wait_write(); | 394 | 109k | let msg = slot.msg.get().read().assume_init(); | 395 | 109k | | 396 | 109k | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 109k | // couldn't because we were busy reading from the slot. | 398 | 109k | if offset + 1 == BLOCK_CAP { | 399 | 3.22k | Block::destroy(block, 0); | 400 | 106k | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 13 | Block::destroy(block, offset + 1); | 402 | 106k | } | 403 | | | 404 | 110k | Ok(msg) | 405 | 110k | } |
<crossbeam_channel::flavors::list::Channel<list::drops::DropCounter>>::read Line | Count | Source | 383 | 471k | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 471k | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 0 | return Err(()); | 387 | 471k | } | 388 | 471k | | 389 | 471k | // Read the message. | 390 | 471k | let block = token.list.block as *mut Block<T>; | 391 | 471k | let offset = token.list.offset; | 392 | 471k | let slot = (*block).slots.get_unchecked(offset); | 393 | 471k | slot.wait_write(); | 394 | 471k | let msg = slot.msg.get().read().assume_init(); | 395 | 471k | | 396 | 471k | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 471k | // couldn't because we were busy reading from the slot. | 398 | 471k | if offset + 1 == BLOCK_CAP { | 399 | 15.1k | Block::destroy(block, 0); | 400 | 456k | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 456k | } | 403 | | | 404 | 471k | Ok(msg) | 405 | 471k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::read Line | Count | Source | 383 | 286k | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 286k | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 1 | return Err(()); | 387 | 286k | } | 388 | 286k | | 389 | 286k | // Read the message. | 390 | 286k | let block = token.list.block as *mut Block<T>; | 391 | 286k | let offset = token.list.offset; | 392 | 286k | let slot = (*block).slots.get_unchecked(offset); | 393 | 286k | slot.wait_write(); | 394 | 286k | let msg = slot.msg.get().read().assume_init(); | 395 | 286k | | 396 | 286k | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 286k | // couldn't because we were busy reading from the slot. | 398 | 286k | if offset + 1 == BLOCK_CAP { | 399 | 9.66k | Block::destroy(block, 0); | 400 | 276k | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 5 | Block::destroy(block, offset + 1); | 402 | 282k | } | 403 | | | 404 | 292k | Ok(msg) | 405 | 292k | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::read Line | Count | Source | 383 | 1.00k | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 1.00k | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 0 | return Err(()); | 387 | 1.00k | } | 388 | 1.00k | | 389 | 1.00k | // Read the message. | 390 | 1.00k | let block = token.list.block as *mut Block<T>; | 391 | 1.00k | let offset = token.list.offset; | 392 | 1.00k | let slot = (*block).slots.get_unchecked(offset); | 393 | 1.00k | slot.wait_write(); | 394 | 1.00k | let msg = slot.msg.get().read().assume_init(); | 395 | 1.00k | | 396 | 1.00k | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 1.00k | // couldn't because we were busy reading from the slot. | 398 | 1.00k | if offset + 1 == BLOCK_CAP { | 399 | 0 | Block::destroy(block, 0); | 400 | 1.00k | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 1.00k | } | 403 | | | 404 | 1.00k | Ok(msg) | 405 | 1.00k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u32>>::read <crossbeam_channel::flavors::list::Channel<i32>>::read Line | Count | Source | 383 | 200k | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 200k | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 0 | return Err(()); | 387 | 200k | } | 388 | 200k | | 389 | 200k | // Read the message. | 390 | 200k | let block = token.list.block as *mut Block<T>; | 391 | 200k | let offset = token.list.offset; | 392 | 200k | let slot = (*block).slots.get_unchecked(offset); | 393 | 200k | slot.wait_write(); | 394 | 200k | let msg = slot.msg.get().read().assume_init(); | 395 | 200k | | 396 | 200k | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 200k | // couldn't because we were busy reading from the slot. | 398 | 200k | if offset + 1 == BLOCK_CAP { | 399 | 6.45k | Block::destroy(block, 0); | 400 | 193k | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 193k | } | 403 | | | 404 | 200k | Ok(msg) | 405 | 200k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i64>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<bool>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u8>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::string::String>>::read Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::read <crossbeam_channel::flavors::list::Channel<i32>>::read Line | Count | Source | 383 | 390k | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 390k | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 11 | return Err(()); | 387 | 390k | } | 388 | 390k | | 389 | 390k | // Read the message. | 390 | 390k | let block = token.list.block as *mut Block<T>; | 391 | 390k | let offset = token.list.offset; | 392 | 390k | let slot = (*block).slots.get_unchecked(offset); | 393 | 390k | slot.wait_write(); | 394 | 390k | let msg = slot.msg.get().read().assume_init(); | 395 | 390k | | 396 | 390k | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 390k | // couldn't because we were busy reading from the slot. | 398 | 390k | if offset + 1 == BLOCK_CAP { | 399 | 12.8k | Block::destroy(block, 0); | 400 | 377k | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 386k | } | 403 | | | 404 | 399k | Ok(msg) | 405 | 399k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::read Line | Count | Source | 383 | 10.0k | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 10.0k | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 0 | return Err(()); | 387 | 10.0k | } | 388 | 10.0k | | 389 | 10.0k | // Read the message. | 390 | 10.0k | let block = token.list.block as *mut Block<T>; | 391 | 10.0k | let offset = token.list.offset; | 392 | 10.0k | let slot = (*block).slots.get_unchecked(offset); | 393 | 10.0k | slot.wait_write(); | 394 | 10.0k | let msg = slot.msg.get().read().assume_init(); | 395 | 10.0k | | 396 | 10.0k | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 10.0k | // couldn't because we were busy reading from the slot. | 398 | 10.0k | if offset + 1 == BLOCK_CAP { | 399 | 322 | Block::destroy(block, 0); | 400 | 9.68k | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 9.68k | } | 403 | | | 404 | 10.0k | Ok(msg) | 405 | 10.0k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::read <crossbeam_channel::flavors::list::Channel<()>>::read Line | Count | Source | 383 | 12.1k | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 12.1k | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 2 | return Err(()); | 387 | 12.1k | } | 388 | 12.1k | | 389 | 12.1k | // Read the message. | 390 | 12.1k | let block = token.list.block as *mut Block<T>; | 391 | 12.1k | let offset = token.list.offset; | 392 | 12.1k | let slot = (*block).slots.get_unchecked(offset); | 393 | 12.1k | slot.wait_write(); | 394 | 12.1k | let msg = slot.msg.get().read().assume_init(); | 395 | 12.1k | | 396 | 12.1k | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 12.1k | // couldn't because we were busy reading from the slot. | 398 | 12.1k | if offset + 1 == BLOCK_CAP { | 399 | 394 | Block::destroy(block, 0); | 400 | 11.7k | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 11.8k | } | 403 | | | 404 | 12.2k | Ok(msg) | 405 | 12.2k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::read Line | Count | Source | 383 | 10.0k | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 10.0k | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 0 | return Err(()); | 387 | 10.0k | } | 388 | 10.0k | | 389 | 10.0k | // Read the message. | 390 | 10.0k | let block = token.list.block as *mut Block<T>; | 391 | 10.0k | let offset = token.list.offset; | 392 | 10.0k | let slot = (*block).slots.get_unchecked(offset); | 393 | 10.0k | slot.wait_write(); | 394 | 10.0k | let msg = slot.msg.get().read().assume_init(); | 395 | 10.0k | | 396 | 10.0k | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 10.0k | // couldn't because we were busy reading from the slot. | 398 | 10.0k | if offset + 1 == BLOCK_CAP { | 399 | 322 | Block::destroy(block, 0); | 400 | 9.68k | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 9.68k | } | 403 | | | 404 | 10.0k | Ok(msg) | 405 | 10.0k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::read Line | Count | Source | 383 | 18 | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 18 | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 7 | return Err(()); | 387 | 11 | } | 388 | 11 | | 389 | 11 | // Read the message. | 390 | 11 | let block = token.list.block as *mut Block<T>; | 391 | 11 | let offset = token.list.offset; | 392 | 11 | let slot = (*block).slots.get_unchecked(offset); | 393 | 11 | slot.wait_write(); | 394 | 11 | let msg = slot.msg.get().read().assume_init(); | 395 | 11 | | 396 | 11 | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 11 | // couldn't because we were busy reading from the slot. | 398 | 11 | if offset + 1 == BLOCK_CAP { | 399 | 0 | Block::destroy(block, 0); | 400 | 11 | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 11 | } | 403 | | | 404 | 11 | Ok(msg) | 405 | 18 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::read <crossbeam_channel::flavors::list::Channel<()>>::read Line | Count | Source | 383 | 44.1k | pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { | 384 | 44.1k | if token.list.block.is_null() { | 385 | | // The channel is disconnected. | 386 | 2 | return Err(()); | 387 | 44.1k | } | 388 | 44.1k | | 389 | 44.1k | // Read the message. | 390 | 44.1k | let block = token.list.block as *mut Block<T>; | 391 | 44.1k | let offset = token.list.offset; | 392 | 44.1k | let slot = (*block).slots.get_unchecked(offset); | 393 | 44.1k | slot.wait_write(); | 394 | 44.1k | let msg = slot.msg.get().read().assume_init(); | 395 | 44.1k | | 396 | 44.1k | // Destroy the block if we've reached the end, or if another thread wanted to destroy but | 397 | 44.1k | // couldn't because we were busy reading from the slot. | 398 | 44.1k | if offset + 1 == BLOCK_CAP { | 399 | 1.42k | Block::destroy(block, 0); | 400 | 42.7k | } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { | 401 | 0 | Block::destroy(block, offset + 1); | 402 | 42.7k | } | 403 | | | 404 | 44.1k | Ok(msg) | 405 | 44.1k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::read |
406 | | |
407 | | /// Attempts to send a message into the channel. |
408 | 52.7k | pub(crate) fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> { |
409 | 52.7k | self.send(msg, None).map_err(|err| match err2 { |
410 | 2 | SendTimeoutError::Disconnected(msg) => TrySendError::Disconnected(msg), |
411 | 0 | SendTimeoutError::Timeout(_) => unreachable!(), |
412 | 52.7k | }2 ) Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::try_send::{closure#0} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::try_send::{closure#0} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::try_send::{closure#0} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::try_send::{closure#0} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::try_send::{closure#0} <crossbeam_channel::flavors::list::Channel<i32>>::try_send::{closure#0} Line | Count | Source | 409 | 2 | self.send(msg, None).map_err(|err| match err { | 410 | 2 | SendTimeoutError::Disconnected(msg) => TrySendError::Disconnected(msg), | 411 | 0 | SendTimeoutError::Timeout(_) => unreachable!(), | 412 | 2 | }) |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<list::drops::DropCounter>>::try_send::{closure#0} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::try_send::{closure#0} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::try_send::{closure#0} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::try_send::{closure#0} |
413 | 52.7k | } Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::try_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::try_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::try_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::try_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::try_send <crossbeam_channel::flavors::list::Channel<i32>>::try_send Line | Count | Source | 408 | 1.00k | pub(crate) fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> { | 409 | 1.00k | self.send(msg, None).map_err(|err| match err { | 410 | | SendTimeoutError::Disconnected(msg) => TrySendError::Disconnected(msg), | 411 | | SendTimeoutError::Timeout(_) => unreachable!(), | 412 | 1.00k | }) | 413 | 1.00k | } |
<crossbeam_channel::flavors::list::Channel<list::drops::DropCounter>>::try_send Line | Count | Source | 408 | 51.7k | pub(crate) fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> { | 409 | 51.7k | self.send(msg, None).map_err(|err| match err { | 410 | | SendTimeoutError::Disconnected(msg) => TrySendError::Disconnected(msg), | 411 | | SendTimeoutError::Timeout(_) => unreachable!(), | 412 | 51.7k | }) | 413 | 51.7k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::try_send Line | Count | Source | 408 | 9 | pub(crate) fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> { | 409 | 9 | self.send(msg, None).map_err(|err| match err { | 410 | | SendTimeoutError::Disconnected(msg) => TrySendError::Disconnected(msg), | 411 | | SendTimeoutError::Timeout(_) => unreachable!(), | 412 | 9 | }) | 413 | 9 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::try_send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::try_send |
414 | | |
415 | | /// Sends a message into the channel. |
416 | 2.22M | pub(crate) fn send( |
417 | 2.22M | &self, |
418 | 2.22M | msg: T, |
419 | 2.22M | _deadline: Option<Instant>, |
420 | 2.22M | ) -> Result<(), SendTimeoutError<T>> { |
421 | 2.22M | let token = &mut Token::default(); |
422 | 2.22M | assert!(self.start_send(token)); |
423 | | unsafe { |
424 | 2.22M | self.write(token, msg) |
425 | 2.22M | .map_err(SendTimeoutError::Disconnected) |
426 | 2.22M | } |
427 | 2.22M | } Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<zero::drops::DropCounter>>::send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::send <crossbeam_channel::flavors::list::Channel<()>>::send Line | Count | Source | 416 | 10.0k | pub(crate) fn send( | 417 | 10.0k | &self, | 418 | 10.0k | msg: T, | 419 | 10.0k | _deadline: Option<Instant>, | 420 | 10.0k | ) -> Result<(), SendTimeoutError<T>> { | 421 | 10.0k | let token = &mut Token::default(); | 422 | 10.0k | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 10.0k | self.write(token, msg) | 425 | 10.0k | .map_err(SendTimeoutError::Disconnected) | 426 | 10.0k | } | 427 | 10.0k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::send Line | Count | Source | 416 | 395k | pub(crate) fn send( | 417 | 395k | &self, | 418 | 395k | msg: T, | 419 | 395k | _deadline: Option<Instant>, | 420 | 395k | ) -> Result<(), SendTimeoutError<T>> { | 421 | 395k | let token = &mut Token::default(); | 422 | 395k | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 395k | self.write(token, msg) | 425 | 395k | .map_err(SendTimeoutError::Disconnected) | 426 | 395k | } | 427 | 395k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::send Line | Count | Source | 416 | 10.0k | pub(crate) fn send( | 417 | 10.0k | &self, | 418 | 10.0k | msg: T, | 419 | 10.0k | _deadline: Option<Instant>, | 420 | 10.0k | ) -> Result<(), SendTimeoutError<T>> { | 421 | 10.0k | let token = &mut Token::default(); | 422 | 10.0k | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 10.0k | self.write(token, msg) | 425 | 10.0k | .map_err(SendTimeoutError::Disconnected) | 426 | 10.0k | } | 427 | 10.0k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::send Line | Count | Source | 416 | 202 | pub(crate) fn send( | 417 | 202 | &self, | 418 | 202 | msg: T, | 419 | 202 | _deadline: Option<Instant>, | 420 | 202 | ) -> Result<(), SendTimeoutError<T>> { | 421 | 202 | let token = &mut Token::default(); | 422 | 202 | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 202 | self.write(token, msg) | 425 | 202 | .map_err(SendTimeoutError::Disconnected) | 426 | 202 | } | 427 | 202 | } |
<crossbeam_channel::flavors::list::Channel<()>>::send Line | Count | Source | 416 | 21.5k | pub(crate) fn send( | 417 | 21.5k | &self, | 418 | 21.5k | msg: T, | 419 | 21.5k | _deadline: Option<Instant>, | 420 | 21.5k | ) -> Result<(), SendTimeoutError<T>> { | 421 | 21.5k | let token = &mut Token::default(); | 422 | 21.5k | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 21.5k | self.write(token, msg) | 425 | 21.5k | .map_err(SendTimeoutError::Disconnected) | 426 | 21.5k | } | 427 | 21.5k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::send Line | Count | Source | 416 | 100k | pub(crate) fn send( | 417 | 100k | &self, | 418 | 100k | msg: T, | 419 | 100k | _deadline: Option<Instant>, | 420 | 100k | ) -> Result<(), SendTimeoutError<T>> { | 421 | 100k | let token = &mut Token::default(); | 422 | 100k | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 100k | self.write(token, msg) | 425 | 100k | .map_err(SendTimeoutError::Disconnected) | 426 | 100k | } | 427 | 100k | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<isize>>>::send Line | Count | Source | 416 | 3 | pub(crate) fn send( | 417 | 3 | &self, | 418 | 3 | msg: T, | 419 | 3 | _deadline: Option<Instant>, | 420 | 3 | ) -> Result<(), SendTimeoutError<T>> { | 421 | 3 | let token = &mut Token::default(); | 422 | 3 | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 3 | self.write(token, msg) | 425 | 3 | .map_err(SendTimeoutError::Disconnected) | 426 | 3 | } | 427 | 3 | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<i32>>>::send Line | Count | Source | 416 | 13 | pub(crate) fn send( | 417 | 13 | &self, | 418 | 13 | msg: T, | 419 | 13 | _deadline: Option<Instant>, | 420 | 13 | ) -> Result<(), SendTimeoutError<T>> { | 421 | 13 | let token = &mut Token::default(); | 422 | 13 | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 13 | self.write(token, msg) | 425 | 13 | .map_err(SendTimeoutError::Disconnected) | 426 | 13 | } | 427 | 13 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<array::drops::DropCounter>>::send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::send <crossbeam_channel::flavors::list::Channel<()>>::send Line | Count | Source | 416 | 48 | pub(crate) fn send( | 417 | 48 | &self, | 418 | 48 | msg: T, | 419 | 48 | _deadline: Option<Instant>, | 420 | 48 | ) -> Result<(), SendTimeoutError<T>> { | 421 | 48 | let token = &mut Token::default(); | 422 | 48 | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 48 | self.write(token, msg) | 425 | 48 | .map_err(SendTimeoutError::Disconnected) | 426 | 48 | } | 427 | 48 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::send Line | Count | Source | 416 | 15 | pub(crate) fn send( | 417 | 15 | &self, | 418 | 15 | msg: T, | 419 | 15 | _deadline: Option<Instant>, | 420 | 15 | ) -> Result<(), SendTimeoutError<T>> { | 421 | 15 | let token = &mut Token::default(); | 422 | 15 | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 15 | self.write(token, msg) | 425 | 15 | .map_err(SendTimeoutError::Disconnected) | 426 | 15 | } | 427 | 15 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::send <crossbeam_channel::flavors::list::Channel<i32>>::send Line | Count | Source | 416 | 2 | pub(crate) fn send( | 417 | 2 | &self, | 418 | 2 | msg: T, | 419 | 2 | _deadline: Option<Instant>, | 420 | 2 | ) -> Result<(), SendTimeoutError<T>> { | 421 | 2 | let token = &mut Token::default(); | 422 | 2 | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 2 | self.write(token, msg) | 425 | 2 | .map_err(SendTimeoutError::Disconnected) | 426 | 2 | } | 427 | 2 | } |
<crossbeam_channel::flavors::list::Channel<list::drops::DropCounter>>::send Line | Count | Source | 416 | 523k | pub(crate) fn send( | 417 | 523k | &self, | 418 | 523k | msg: T, | 419 | 523k | _deadline: Option<Instant>, | 420 | 523k | ) -> Result<(), SendTimeoutError<T>> { | 421 | 523k | let token = &mut Token::default(); | 422 | 523k | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 523k | self.write(token, msg) | 425 | 523k | .map_err(SendTimeoutError::Disconnected) | 426 | 523k | } | 427 | 523k | } |
<crossbeam_channel::flavors::list::Channel<()>>::send Line | Count | Source | 416 | 127k | pub(crate) fn send( | 417 | 127k | &self, | 418 | 127k | msg: T, | 419 | 127k | _deadline: Option<Instant>, | 420 | 127k | ) -> Result<(), SendTimeoutError<T>> { | 421 | 127k | let token = &mut Token::default(); | 422 | 127k | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 127k | self.write(token, msg) | 425 | 127k | .map_err(SendTimeoutError::Disconnected) | 426 | 127k | } | 427 | 127k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::send Line | Count | Source | 416 | 279k | pub(crate) fn send( | 417 | 279k | &self, | 418 | 279k | msg: T, | 419 | 279k | _deadline: Option<Instant>, | 420 | 279k | ) -> Result<(), SendTimeoutError<T>> { | 421 | 279k | let token = &mut Token::default(); | 422 | 279k | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 279k | self.write(token, msg) | 425 | 279k | .map_err(SendTimeoutError::Disconnected) | 426 | 279k | } | 427 | 279k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::send Line | Count | Source | 416 | 112k | pub(crate) fn send( | 417 | 112k | &self, | 418 | 112k | msg: T, | 419 | 112k | _deadline: Option<Instant>, | 420 | 112k | ) -> Result<(), SendTimeoutError<T>> { | 421 | 112k | let token = &mut Token::default(); | 422 | 112k | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 112k | self.write(token, msg) | 425 | 112k | .map_err(SendTimeoutError::Disconnected) | 426 | 112k | } | 427 | 112k | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::send Line | Count | Source | 416 | 1.00k | pub(crate) fn send( | 417 | 1.00k | &self, | 418 | 1.00k | msg: T, | 419 | 1.00k | _deadline: Option<Instant>, | 420 | 1.00k | ) -> Result<(), SendTimeoutError<T>> { | 421 | 1.00k | let token = &mut Token::default(); | 422 | 1.00k | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 1.00k | self.write(token, msg) | 425 | 1.00k | .map_err(SendTimeoutError::Disconnected) | 426 | 1.00k | } | 427 | 1.00k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any>>>::send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<bool>>::send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::string::String>>::send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u8>>::send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::send Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i64>>::send <crossbeam_channel::flavors::list::Channel<i32>>::send Line | Count | Source | 416 | 200k | pub(crate) fn send( | 417 | 200k | &self, | 418 | 200k | msg: T, | 419 | 200k | _deadline: Option<Instant>, | 420 | 200k | ) -> Result<(), SendTimeoutError<T>> { | 421 | 200k | let token = &mut Token::default(); | 422 | 200k | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 200k | self.write(token, msg) | 425 | 200k | .map_err(SendTimeoutError::Disconnected) | 426 | 200k | } | 427 | 200k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::send Line | Count | Source | 416 | 10.0k | pub(crate) fn send( | 417 | 10.0k | &self, | 418 | 10.0k | msg: T, | 419 | 10.0k | _deadline: Option<Instant>, | 420 | 10.0k | ) -> Result<(), SendTimeoutError<T>> { | 421 | 10.0k | let token = &mut Token::default(); | 422 | 10.0k | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 10.0k | self.write(token, msg) | 425 | 10.0k | .map_err(SendTimeoutError::Disconnected) | 426 | 10.0k | } | 427 | 10.0k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::send Line | Count | Source | 416 | 395k | pub(crate) fn send( | 417 | 395k | &self, | 418 | 395k | msg: T, | 419 | 395k | _deadline: Option<Instant>, | 420 | 395k | ) -> Result<(), SendTimeoutError<T>> { | 421 | 395k | let token = &mut Token::default(); | 422 | 395k | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 395k | self.write(token, msg) | 425 | 395k | .map_err(SendTimeoutError::Disconnected) | 426 | 395k | } | 427 | 395k | } |
<crossbeam_channel::flavors::list::Channel<()>>::send Line | Count | Source | 416 | 19.6k | pub(crate) fn send( | 417 | 19.6k | &self, | 418 | 19.6k | msg: T, | 419 | 19.6k | _deadline: Option<Instant>, | 420 | 19.6k | ) -> Result<(), SendTimeoutError<T>> { | 421 | 19.6k | let token = &mut Token::default(); | 422 | 19.6k | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 19.6k | self.write(token, msg) | 425 | 19.6k | .map_err(SendTimeoutError::Disconnected) | 426 | 19.6k | } | 427 | 19.6k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::send Line | Count | Source | 416 | 10.0k | pub(crate) fn send( | 417 | 10.0k | &self, | 418 | 10.0k | msg: T, | 419 | 10.0k | _deadline: Option<Instant>, | 420 | 10.0k | ) -> Result<(), SendTimeoutError<T>> { | 421 | 10.0k | let token = &mut Token::default(); | 422 | 10.0k | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 10.0k | self.write(token, msg) | 425 | 10.0k | .map_err(SendTimeoutError::Disconnected) | 426 | 10.0k | } | 427 | 10.0k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::send <crossbeam_channel::flavors::list::Channel<i32>>::send Line | Count | Source | 416 | 14 | pub(crate) fn send( | 417 | 14 | &self, | 418 | 14 | msg: T, | 419 | 14 | _deadline: Option<Instant>, | 420 | 14 | ) -> Result<(), SendTimeoutError<T>> { | 421 | 14 | let token = &mut Token::default(); | 422 | 14 | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 14 | self.write(token, msg) | 425 | 14 | .map_err(SendTimeoutError::Disconnected) | 426 | 14 | } | 427 | 14 | } |
<crossbeam_channel::flavors::list::Channel<()>>::send Line | Count | Source | 416 | 10.0k | pub(crate) fn send( | 417 | 10.0k | &self, | 418 | 10.0k | msg: T, | 419 | 10.0k | _deadline: Option<Instant>, | 420 | 10.0k | ) -> Result<(), SendTimeoutError<T>> { | 421 | 10.0k | let token = &mut Token::default(); | 422 | 10.0k | assert!(self.start_send(token)); | 423 | | unsafe { | 424 | 10.0k | self.write(token, msg) | 425 | 10.0k | .map_err(SendTimeoutError::Disconnected) | 426 | 10.0k | } | 427 | 10.0k | } |
|
428 | | |
429 | | /// Attempts to receive a message without blocking. |
430 | 1.14M | pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { |
431 | 1.14M | let token = &mut Token::default(); |
432 | 1.14M | |
433 | 1.14M | if self.start_recv(token) { |
434 | 653k | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected18 ) } <crossbeam_channel::flavors::list::Channel<()>>::try_recv::{closure#0} Line | Count | Source | 434 | 1 | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } |
<crossbeam_channel::flavors::list::Channel<i32>>::try_recv::{closure#0} Line | Count | Source | 434 | 4 | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } |
<crossbeam_channel::flavors::list::Channel<i32>>::try_recv::{closure#0} Line | Count | Source | 434 | 1 | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } |
<crossbeam_channel::flavors::list::Channel<i32>>::try_recv::{closure#0} Line | Count | Source | 434 | 2 | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } |
<crossbeam_channel::flavors::list::Channel<()>>::try_recv::{closure#0} Line | Count | Source | 434 | 1 | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } |
<crossbeam_channel::flavors::list::Channel<()>>::try_recv::{closure#0} Line | Count | Source | 434 | 2 | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } |
<crossbeam_channel::flavors::list::Channel<i32>>::try_recv::{closure#0} Line | Count | Source | 434 | 7 | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } |
|
435 | | } else { |
436 | 496k | Err(TryRecvError::Empty) |
437 | | } |
438 | 1.14M | } Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::try_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::try_recv <crossbeam_channel::flavors::list::Channel<i32>>::try_recv Line | Count | Source | 430 | 397k | pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { | 431 | 397k | let token = &mut Token::default(); | 432 | 397k | | 433 | 397k | if self.start_recv(token) { | 434 | 199k | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } | 435 | | } else { | 436 | 197k | Err(TryRecvError::Empty) | 437 | | } | 438 | 397k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::try_recv <crossbeam_channel::flavors::list::Channel<()>>::try_recv Line | Count | Source | 430 | 2 | pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { | 431 | 2 | let token = &mut Token::default(); | 432 | 2 | | 433 | 2 | if self.start_recv(token) { | 434 | 1 | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } | 435 | | } else { | 436 | 1 | Err(TryRecvError::Empty) | 437 | | } | 438 | 2 | } |
<crossbeam_channel::flavors::list::Channel<()>>::try_recv Line | Count | Source | 430 | 2 | pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { | 431 | 2 | let token = &mut Token::default(); | 432 | 2 | | 433 | 2 | if self.start_recv(token) { | 434 | 0 | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } | 435 | | } else { | 436 | 2 | Err(TryRecvError::Empty) | 437 | | } | 438 | 2 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::try_recv Line | Count | Source | 430 | 1.61k | pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { | 431 | 1.61k | let token = &mut Token::default(); | 432 | 1.61k | | 433 | 1.61k | if self.start_recv(token) { | 434 | 9 | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } | 435 | | } else { | 436 | 1.61k | Err(TryRecvError::Empty) | 437 | | } | 438 | 1.61k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::try_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::try_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::try_recv <crossbeam_channel::flavors::list::Channel<i32>>::try_recv Line | Count | Source | 430 | 51 | pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { | 431 | 51 | let token = &mut Token::default(); | 432 | 51 | | 433 | 51 | if self.start_recv(token) { | 434 | 3 | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } | 435 | | } else { | 436 | 48 | Err(TryRecvError::Empty) | 437 | | } | 438 | 51 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::try_recv Line | Count | Source | 430 | 1 | pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { | 431 | 1 | let token = &mut Token::default(); | 432 | 1 | | 433 | 1 | if self.start_recv(token) { | 434 | 1 | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } | 435 | | } else { | 436 | 0 | Err(TryRecvError::Empty) | 437 | | } | 438 | 1 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::try_recv <crossbeam_channel::flavors::list::Channel<usize>>::try_recv Line | Count | Source | 430 | 200k | pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { | 431 | 200k | let token = &mut Token::default(); | 432 | 200k | | 433 | 200k | if self.start_recv(token) { | 434 | 100k | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } | 435 | | } else { | 436 | 100k | Err(TryRecvError::Empty) | 437 | | } | 438 | 200k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::try_recv Line | Count | Source | 430 | 99.9k | pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { | 431 | 99.9k | let token = &mut Token::default(); | 432 | 99.9k | | 433 | 99.9k | if self.start_recv(token) { | 434 | 99.9k | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } | 435 | | } else { | 436 | 18.4E | Err(TryRecvError::Empty) | 437 | | } | 438 | 99.9k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::try_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::string::String>>::try_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<bool>>::try_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i64>>::try_recv <crossbeam_channel::flavors::list::Channel<i32>>::try_recv Line | Count | Source | 430 | 396k | pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { | 431 | 396k | let token = &mut Token::default(); | 432 | 396k | | 433 | 396k | if self.start_recv(token) { | 434 | 199k | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } | 435 | | } else { | 436 | 197k | Err(TryRecvError::Empty) | 437 | | } | 438 | 396k | } |
<crossbeam_channel::flavors::list::Channel<()>>::try_recv Line | Count | Source | 430 | 3 | pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { | 431 | 3 | let token = &mut Token::default(); | 432 | 3 | | 433 | 3 | if self.start_recv(token) { | 434 | 1 | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } | 435 | | } else { | 436 | 2 | Err(TryRecvError::Empty) | 437 | | } | 438 | 3 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::try_recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::try_recv <crossbeam_channel::flavors::list::Channel<()>>::try_recv Line | Count | Source | 430 | 44.1k | pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { | 431 | 44.1k | let token = &mut Token::default(); | 432 | 44.1k | | 433 | 44.1k | if self.start_recv(token) { | 434 | 44.1k | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } | 435 | | } else { | 436 | 18.4E | Err(TryRecvError::Empty) | 437 | | } | 438 | 44.1k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::try_recv <crossbeam_channel::flavors::list::Channel<i32>>::try_recv Line | Count | Source | 430 | 17 | pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { | 431 | 17 | let token = &mut Token::default(); | 432 | 17 | | 433 | 17 | if self.start_recv(token) { | 434 | 17 | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } | 435 | | } else { | 436 | 0 | Err(TryRecvError::Empty) | 437 | | } | 438 | 17 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::try_recv Line | Count | Source | 430 | 10.0k | pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { | 431 | 10.0k | let token = &mut Token::default(); | 432 | 10.0k | | 433 | 10.0k | if self.start_recv(token) { | 434 | 10.0k | unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } | 435 | | } else { | 436 | 0 | Err(TryRecvError::Empty) | 437 | | } | 438 | 10.0k | } |
|
439 | | |
440 | | /// Receives a message from the channel. |
441 | 879k | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { |
442 | 879k | let token = &mut Token::default(); |
443 | | loop { |
444 | | // Try receiving a message several times. |
445 | 881k | let backoff = Backoff::new(); |
446 | 1.06M | loop { |
447 | 1.06M | if self.start_recv(token) { |
448 | | unsafe { |
449 | 886k | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected29 ); <crossbeam_channel::flavors::list::Channel<i32>>::recv::{closure#0} Line | Count | Source | 449 | 9 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<i32>>>::recv::{closure#0} Line | Count | Source | 449 | 1 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); |
<crossbeam_channel::flavors::list::Channel<usize>>::recv::{closure#0} Line | Count | Source | 449 | 2 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); |
<crossbeam_channel::flavors::list::Channel<()>>::recv::{closure#0} Line | Count | Source | 449 | 4 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); |
<crossbeam_channel::flavors::list::Channel<i32>>::recv::{closure#0} Line | Count | Source | 449 | 2 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); |
<crossbeam_channel::flavors::list::Channel<i32>>::recv::{closure#0} Line | Count | Source | 449 | 3 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); |
<crossbeam_channel::flavors::list::Channel<()>>::recv::{closure#0} Line | Count | Source | 449 | 2 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); |
<crossbeam_channel::flavors::list::Channel<usize>>::recv::{closure#0} Line | Count | Source | 449 | 1 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); |
<crossbeam_channel::flavors::list::Channel<i32>>::recv::{closure#0} Line | Count | Source | 449 | 4 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); |
<crossbeam_channel::flavors::list::Channel<()>>::recv::{closure#0} Line | Count | Source | 449 | 1 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); |
|
450 | | } |
451 | 179k | } |
452 | 179k | |
453 | 179k | if backoff.is_completed() { |
454 | 18.4E | break; |
455 | 184k | } else { |
456 | 184k | backoff.snooze(); |
457 | 184k | } |
458 | | } |
459 | | |
460 | 18.4E | if let Some(d18.4E ) = deadline { |
461 | 18.4E | if Instant::now() >= d { |
462 | 73 | return Err(RecvTimeoutError::Timeout); |
463 | 226 | } |
464 | 1.84k | } |
465 | | |
466 | | // Prepare for blocking until a sender wakes us up. |
467 | 2.07k | Context::with(|cx| { |
468 | 2.07k | let oper = Operation::hook(token); |
469 | 2.07k | self.receivers.register(oper, cx); |
470 | | |
471 | | // Has the channel become ready just now? |
472 | 2.07k | if !self.is_empty() || self.is_disconnected()527 { |
473 | 1.54k | let _ = cx.try_select(Selected::Aborted); |
474 | 1.54k | }527 |
475 | | |
476 | | // Block the current thread. |
477 | 2.07k | let sel = cx.wait_until(deadline); |
478 | 2.07k | |
479 | 2.07k | match sel { |
480 | 2.07k | Selected::Waiting => unreachable!()0 , |
481 | 1.64k | Selected::Aborted | Selected::Disconnected => { |
482 | 1.64k | self.receivers.unregister(oper).unwrap(); |
483 | 1.64k | // If the channel was disconnected, we still have to check for remaining |
484 | 1.64k | // messages. |
485 | 1.64k | } |
486 | 428 | Selected::Operation(_) => {} |
487 | | } |
488 | 2.07k | }); Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<zero::drops::DropCounter>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::recv::{closure#1} <crossbeam_channel::flavors::list::Channel<()>>::recv::{closure#1} Line | Count | Source | 467 | 1 | Context::with(|cx| { | 468 | 1 | let oper = Operation::hook(token); | 469 | 1 | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | 1 | if !self.is_empty() || self.is_disconnected() { | 473 | 0 | let _ = cx.try_select(Selected::Aborted); | 474 | 1 | } | 475 | | | 476 | | // Block the current thread. | 477 | 1 | let sel = cx.wait_until(deadline); | 478 | 1 | | 479 | 1 | match sel { | 480 | 1 | Selected::Waiting => unreachable!()0 , | 481 | 0 | Selected::Aborted | Selected::Disconnected => { | 482 | 0 | self.receivers.unregister(oper).unwrap(); | 483 | 0 | // If the channel was disconnected, we still have to check for remaining | 484 | 0 | // messages. | 485 | 0 | } | 486 | 1 | Selected::Operation(_) => {} | 487 | | } | 488 | 1 | }); |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::recv::{closure#1} <crossbeam_channel::flavors::list::Channel<i32>>::recv::{closure#1} Line | Count | Source | 467 | 1 | Context::with(|cx| { | 468 | 1 | let oper = Operation::hook(token); | 469 | 1 | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | 1 | if !self.is_empty() || self.is_disconnected() { | 473 | 0 | let _ = cx.try_select(Selected::Aborted); | 474 | 1 | } | 475 | | | 476 | | // Block the current thread. | 477 | 1 | let sel = cx.wait_until(deadline); | 478 | 1 | | 479 | 1 | match sel { | 480 | 1 | Selected::Waiting => unreachable!()0 , | 481 | 0 | Selected::Aborted | Selected::Disconnected => { | 482 | 0 | self.receivers.unregister(oper).unwrap(); | 483 | 0 | // If the channel was disconnected, we still have to check for remaining | 484 | 0 | // messages. | 485 | 0 | } | 486 | 1 | Selected::Operation(_) => {} | 487 | | } | 488 | 1 | }); |
<crossbeam_channel::flavors::list::Channel<usize>>::recv::{closure#1} Line | Count | Source | 467 | 218 | Context::with(|cx| { | 468 | 218 | let oper = Operation::hook(token); | 469 | 218 | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | 218 | if !self.is_empty() || self.is_disconnected() { | 473 | 0 | let _ = cx.try_select(Selected::Aborted); | 474 | 218 | } | 475 | | | 476 | | // Block the current thread. | 477 | 218 | let sel = cx.wait_until(deadline); | 478 | 218 | | 479 | 218 | match sel { | 480 | 218 | Selected::Waiting => unreachable!()0 , | 481 | 93 | Selected::Aborted | Selected::Disconnected => { | 482 | 93 | self.receivers.unregister(oper).unwrap(); | 483 | 93 | // If the channel was disconnected, we still have to check for remaining | 484 | 93 | // messages. | 485 | 93 | } | 486 | 125 | Selected::Operation(_) => {} | 487 | | } | 488 | 218 | }); |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<i32>>>::recv::{closure#1} <crossbeam_channel::flavors::list::Channel<i32>>::recv::{closure#1} Line | Count | Source | 467 | 1 | Context::with(|cx| { | 468 | 1 | let oper = Operation::hook(token); | 469 | 1 | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | 1 | if !self.is_empty() || self.is_disconnected() { | 473 | 0 | let _ = cx.try_select(Selected::Aborted); | 474 | 1 | } | 475 | | | 476 | | // Block the current thread. | 477 | 1 | let sel = cx.wait_until(deadline); | 478 | 1 | | 479 | 1 | match sel { | 480 | 1 | Selected::Waiting => unreachable!()0 , | 481 | 0 | Selected::Aborted | Selected::Disconnected => { | 482 | 0 | self.receivers.unregister(oper).unwrap(); | 483 | 0 | // If the channel was disconnected, we still have to check for remaining | 484 | 0 | // messages. | 485 | 0 | } | 486 | 1 | Selected::Operation(_) => {} | 487 | | } | 488 | 1 | }); |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<isize>>>::recv::{closure#1} <crossbeam_channel::flavors::list::Channel<()>>::recv::{closure#1} Line | Count | Source | 467 | 8 | Context::with(|cx| { | 468 | 8 | let oper = Operation::hook(token); | 469 | 8 | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | 8 | if !self.is_empty() || self.is_disconnected()7 { | 473 | 1 | let _ = cx.try_select(Selected::Aborted); | 474 | 7 | } | 475 | | | 476 | | // Block the current thread. | 477 | 8 | let sel = cx.wait_until(deadline); | 478 | 8 | | 479 | 8 | match sel { | 480 | 8 | Selected::Waiting => unreachable!()0 , | 481 | 3 | Selected::Aborted | Selected::Disconnected => { | 482 | 3 | self.receivers.unregister(oper).unwrap(); | 483 | 3 | // If the channel was disconnected, we still have to check for remaining | 484 | 3 | // messages. | 485 | 3 | } | 486 | 5 | Selected::Operation(_) => {} | 487 | | } | 488 | 8 | }); |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<array::drops::DropCounter>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::recv::{closure#1} <crossbeam_channel::flavors::list::Channel<()>>::recv::{closure#1} Line | Count | Source | 467 | 1 | Context::with(|cx| { | 468 | 1 | let oper = Operation::hook(token); | 469 | 1 | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | 1 | if !self.is_empty() || self.is_disconnected() { | 473 | 0 | let _ = cx.try_select(Selected::Aborted); | 474 | 1 | } | 475 | | | 476 | | // Block the current thread. | 477 | 1 | let sel = cx.wait_until(deadline); | 478 | 1 | | 479 | 1 | match sel { | 480 | 1 | Selected::Waiting => unreachable!()0 , | 481 | 0 | Selected::Aborted | Selected::Disconnected => { | 482 | 0 | self.receivers.unregister(oper).unwrap(); | 483 | 0 | // If the channel was disconnected, we still have to check for remaining | 484 | 0 | // messages. | 485 | 0 | } | 486 | 1 | Selected::Operation(_) => {} | 487 | | } | 488 | 1 | }); |
<crossbeam_channel::flavors::list::Channel<i32>>::recv::{closure#1} Line | Count | Source | 467 | 1 | Context::with(|cx| { | 468 | 1 | let oper = Operation::hook(token); | 469 | 1 | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | 1 | if !self.is_empty() || self.is_disconnected() { | 473 | 0 | let _ = cx.try_select(Selected::Aborted); | 474 | 1 | } | 475 | | | 476 | | // Block the current thread. | 477 | 1 | let sel = cx.wait_until(deadline); | 478 | 1 | | 479 | 1 | match sel { | 480 | 1 | Selected::Waiting => unreachable!()0 , | 481 | 0 | Selected::Aborted | Selected::Disconnected => { | 482 | 0 | self.receivers.unregister(oper).unwrap(); | 483 | 0 | // If the channel was disconnected, we still have to check for remaining | 484 | 0 | // messages. | 485 | 0 | } | 486 | 1 | Selected::Operation(_) => {} | 487 | | } | 488 | 1 | }); |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::recv::{closure#1} <crossbeam_channel::flavors::list::Channel<usize>>::recv::{closure#1} Line | Count | Source | 467 | 2 | Context::with(|cx| { | 468 | 2 | let oper = Operation::hook(token); | 469 | 2 | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | 2 | if !self.is_empty() || self.is_disconnected() { | 473 | 0 | let _ = cx.try_select(Selected::Aborted); | 474 | 2 | } | 475 | | | 476 | | // Block the current thread. | 477 | 2 | let sel = cx.wait_until(deadline); | 478 | 2 | | 479 | 2 | match sel { | 480 | 2 | Selected::Waiting => unreachable!()0 , | 481 | 0 | Selected::Aborted | Selected::Disconnected => { | 482 | 0 | self.receivers.unregister(oper).unwrap(); | 483 | 0 | // If the channel was disconnected, we still have to check for remaining | 484 | 0 | // messages. | 485 | 0 | } | 486 | 2 | Selected::Operation(_) => {} | 487 | | } | 488 | 2 | }); |
<crossbeam_channel::flavors::list::Channel<()>>::recv::{closure#1} Line | Count | Source | 467 | 25 | Context::with(|cx| { | 468 | 25 | let oper = Operation::hook(token); | 469 | 25 | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | 25 | if !self.is_empty() || self.is_disconnected()11 { | 473 | 14 | let _ = cx.try_select(Selected::Aborted); | 474 | 14 | }11 | 475 | | | 476 | | // Block the current thread. | 477 | 25 | let sel = cx.wait_until(deadline); | 478 | 25 | | 479 | 25 | match sel { | 480 | 25 | Selected::Waiting => unreachable!()0 , | 481 | 15 | Selected::Aborted | Selected::Disconnected => { | 482 | 15 | self.receivers.unregister(oper).unwrap(); | 483 | 15 | // If the channel was disconnected, we still have to check for remaining | 484 | 15 | // messages. | 485 | 15 | } | 486 | 10 | Selected::Operation(_) => {} | 487 | | } | 488 | 25 | }); |
<crossbeam_channel::flavors::list::Channel<list::drops::DropCounter>>::recv::{closure#1} Line | Count | Source | 467 | 43 | Context::with(|cx| { | 468 | 43 | let oper = Operation::hook(token); | 469 | 43 | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | 43 | if !self.is_empty() || self.is_disconnected()9 { | 473 | 34 | let _ = cx.try_select(Selected::Aborted); | 474 | 34 | }9 | 475 | | | 476 | | // Block the current thread. | 477 | 43 | let sel = cx.wait_until(deadline); | 478 | 43 | | 479 | 43 | match sel { | 480 | 43 | Selected::Waiting => unreachable!()0 , | 481 | 34 | Selected::Aborted | Selected::Disconnected => { | 482 | 34 | self.receivers.unregister(oper).unwrap(); | 483 | 34 | // If the channel was disconnected, we still have to check for remaining | 484 | 34 | // messages. | 485 | 34 | } | 486 | 9 | Selected::Operation(_) => {} | 487 | | } | 488 | 43 | }); |
<crossbeam_channel::flavors::list::Channel<i32>>::recv::{closure#1} Line | Count | Source | 467 | 1.76k | Context::with(|cx| { | 468 | 1.76k | let oper = Operation::hook(token); | 469 | 1.76k | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | 1.76k | if !self.is_empty() || self.is_disconnected()272 { | 473 | 1.49k | let _ = cx.try_select(Selected::Aborted); | 474 | 1.49k | }272 | 475 | | | 476 | | // Block the current thread. | 477 | 1.76k | let sel = cx.wait_until(deadline); | 478 | 1.76k | | 479 | 1.76k | match sel { | 480 | 1.76k | Selected::Waiting => unreachable!()0 , | 481 | 1.49k | Selected::Aborted | Selected::Disconnected => { | 482 | 1.49k | self.receivers.unregister(oper).unwrap(); | 483 | 1.49k | // If the channel was disconnected, we still have to check for remaining | 484 | 1.49k | // messages. | 485 | 1.49k | } | 486 | 270 | Selected::Operation(_) => {} | 487 | | } | 488 | 1.76k | }); |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u32>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i64>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u8>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::string::String>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<bool>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::recv::{closure#1} <crossbeam_channel::flavors::list::Channel<i32>>::recv::{closure#1} Line | Count | Source | 467 | 2 | Context::with(|cx| { | 468 | 2 | let oper = Operation::hook(token); | 469 | 2 | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | 2 | if !self.is_empty() || self.is_disconnected() { | 473 | 0 | let _ = cx.try_select(Selected::Aborted); | 474 | 2 | } | 475 | | | 476 | | // Block the current thread. | 477 | 2 | let sel = cx.wait_until(deadline); | 478 | 2 | | 479 | 2 | match sel { | 480 | 2 | Selected::Waiting => unreachable!()0 , | 481 | 1 | Selected::Aborted | Selected::Disconnected => { | 482 | 1 | self.receivers.unregister(oper).unwrap(); | 483 | 1 | // If the channel was disconnected, we still have to check for remaining | 484 | 1 | // messages. | 485 | 1 | } | 486 | 1 | Selected::Operation(_) => {} | 487 | | } | 488 | 2 | }); |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::recv::{closure#1} <crossbeam_channel::flavors::list::Channel<i32>>::recv::{closure#1} Line | Count | Source | 467 | 1 | Context::with(|cx| { | 468 | 1 | let oper = Operation::hook(token); | 469 | 1 | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | 1 | if !self.is_empty() || self.is_disconnected() { | 473 | 0 | let _ = cx.try_select(Selected::Aborted); | 474 | 1 | } | 475 | | | 476 | | // Block the current thread. | 477 | 1 | let sel = cx.wait_until(deadline); | 478 | 1 | | 479 | 1 | match sel { | 480 | 1 | Selected::Waiting => unreachable!()0 , | 481 | 0 | Selected::Aborted | Selected::Disconnected => { | 482 | 0 | self.receivers.unregister(oper).unwrap(); | 483 | 0 | // If the channel was disconnected, we still have to check for remaining | 484 | 0 | // messages. | 485 | 0 | } | 486 | 1 | Selected::Operation(_) => {} | 487 | | } | 488 | 1 | }); |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::recv::{closure#1} Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::recv::{closure#1} |
489 | | } |
490 | 886k | } Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<zero::drops::DropCounter>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::recv <crossbeam_channel::flavors::list::Channel<i32>>::recv Line | Count | Source | 441 | 1 | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 1 | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 2 | let backoff = Backoff::new(); | 446 | 13 | loop { | 447 | 13 | if self.start_recv(token) { | 448 | | unsafe { | 449 | 1 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 12 | } | 452 | 12 | | 453 | 12 | if backoff.is_completed() { | 454 | 1 | break; | 455 | 11 | } else { | 456 | 11 | backoff.snooze(); | 457 | 11 | } | 458 | | } | 459 | | | 460 | 1 | if let Some(d0 ) = deadline { | 461 | 0 | if Instant::now() >= d { | 462 | 0 | return Err(RecvTimeoutError::Timeout); | 463 | 0 | } | 464 | 1 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 1 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 1 | }); | 489 | | } | 490 | 1 | } |
<crossbeam_channel::flavors::list::Channel<()>>::recv Line | Count | Source | 441 | 3 | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 3 | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 4 | let backoff = Backoff::new(); | 446 | 22 | loop { | 447 | 22 | if self.start_recv(token) { | 448 | | unsafe { | 449 | 3 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 19 | } | 452 | 19 | | 453 | 19 | if backoff.is_completed() { | 454 | 1 | break; | 455 | 18 | } else { | 456 | 18 | backoff.snooze(); | 457 | 18 | } | 458 | | } | 459 | | | 460 | 1 | if let Some(d0 ) = deadline { | 461 | 0 | if Instant::now() >= d { | 462 | 0 | return Err(RecvTimeoutError::Timeout); | 463 | 0 | } | 464 | 1 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 1 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 1 | }); | 489 | | } | 490 | 3 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::recv Line | Count | Source | 441 | 88.8k | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 88.8k | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 88.8k | let backoff = Backoff::new(); | 446 | 89.0k | loop { | 447 | 89.0k | if self.start_recv(token) { | 448 | | unsafe { | 449 | 89.6k | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 18.4E | } | 452 | 18.4E | | 453 | 18.4E | if backoff.is_completed() { | 454 | 18.4E | break; | 455 | 154 | } else { | 456 | 154 | backoff.snooze(); | 457 | 154 | } | 458 | | } | 459 | | | 460 | 18.4E | if let Some(d18.4E ) = deadline { | 461 | 18.4E | if Instant::now() >= d { | 462 | 0 | return Err(RecvTimeoutError::Timeout); | 463 | 0 | } | 464 | 1 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 1 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 1 | }); | 489 | | } | 490 | 89.6k | } |
<crossbeam_channel::flavors::list::Channel<()>>::recv Line | Count | Source | 441 | 20.1k | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 20.1k | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 20.1k | let backoff = Backoff::new(); | 446 | 56.1k | loop { | 447 | 56.1k | if self.start_recv(token) { | 448 | | unsafe { | 449 | 20.1k | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 36.0k | } | 452 | 36.0k | | 453 | 36.0k | if backoff.is_completed() { | 454 | 11 | break; | 455 | 36.0k | } else { | 456 | 36.0k | backoff.snooze(); | 457 | 36.0k | } | 458 | | } | 459 | | | 460 | 11 | if let Some(d5 ) = deadline { | 461 | 5 | if Instant::now() >= d { | 462 | 3 | return Err(RecvTimeoutError::Timeout); | 463 | 2 | } | 464 | 6 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 8 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 8 | }); | 489 | | } | 490 | 20.1k | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<isize>>>::recv Line | Count | Source | 441 | 1 | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 1 | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 1 | let backoff = Backoff::new(); | 446 | 9 | loop { | 447 | 9 | if self.start_recv(token) { | 448 | | unsafe { | 449 | 1 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 8 | } | 452 | 8 | | 453 | 8 | if backoff.is_completed() { | 454 | 0 | break; | 455 | 8 | } else { | 456 | 8 | backoff.snooze(); | 457 | 8 | } | 458 | | } | 459 | | | 460 | 0 | if let Some(d) = deadline { | 461 | 0 | if Instant::now() >= d { | 462 | 0 | return Err(RecvTimeoutError::Timeout); | 463 | 0 | } | 464 | 0 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 0 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 0 | }); | 489 | | } | 490 | 1 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::recv Line | Count | Source | 441 | 272 | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 272 | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 490 | let backoff = Backoff::new(); | 446 | 3.72k | loop { | 447 | 3.72k | if self.start_recv(token) { | 448 | | unsafe { | 449 | 204 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 3.51k | } | 452 | 3.51k | | 453 | 3.51k | if backoff.is_completed() { | 454 | 286 | break; | 455 | 3.23k | } else { | 456 | 3.23k | backoff.snooze(); | 457 | 3.23k | } | 458 | | } | 459 | | | 460 | 286 | if let Some(d) = deadline { | 461 | 286 | if Instant::now() >= d { | 462 | 68 | return Err(RecvTimeoutError::Timeout); | 463 | 218 | } | 464 | 0 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 218 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 218 | }); | 489 | | } | 490 | 272 | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<i32>>>::recv Line | Count | Source | 441 | 13 | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 13 | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 13 | let backoff = Backoff::new(); | 446 | 29 | loop { | 447 | 29 | if self.start_recv(token) { | 448 | | unsafe { | 449 | 13 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 16 | } | 452 | 16 | | 453 | 16 | if backoff.is_completed() { | 454 | 0 | break; | 455 | 16 | } else { | 456 | 16 | backoff.snooze(); | 457 | 16 | } | 458 | | } | 459 | | | 460 | 0 | if let Some(d) = deadline { | 461 | 0 | if Instant::now() >= d { | 462 | 0 | return Err(RecvTimeoutError::Timeout); | 463 | 0 | } | 464 | 0 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 0 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 0 | }); | 489 | | } | 490 | 13 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<array::drops::DropCounter>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::recv <crossbeam_channel::flavors::list::Channel<i32>>::recv Line | Count | Source | 441 | 12 | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 12 | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 13 | let backoff = Backoff::new(); | 446 | 31 | loop { | 447 | 31 | if self.start_recv(token) { | 448 | | unsafe { | 449 | 14 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 17 | } | 452 | 17 | | 453 | 17 | if backoff.is_completed() { | 454 | 18.4E | break; | 455 | 18 | } else { | 456 | 18 | backoff.snooze(); | 457 | 18 | } | 458 | | } | 459 | | | 460 | 18.4E | if let Some(d18.4E ) = deadline { | 461 | 18.4E | if Instant::now() >= d { | 462 | 0 | return Err(RecvTimeoutError::Timeout); | 463 | 0 | } | 464 | 1 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 1 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 1 | }); | 489 | | } | 490 | 14 | } |
<crossbeam_channel::flavors::list::Channel<()>>::recv Line | Count | Source | 441 | 4 | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 4 | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 5 | let backoff = Backoff::new(); | 446 | 16 | loop { | 447 | 16 | if self.start_recv(token) { | 448 | | unsafe { | 449 | 4 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 12 | } | 452 | 12 | | 453 | 12 | if backoff.is_completed() { | 454 | 1 | break; | 455 | 11 | } else { | 456 | 11 | backoff.snooze(); | 457 | 11 | } | 458 | | } | 459 | | | 460 | 1 | if let Some(d0 ) = deadline { | 461 | 0 | if Instant::now() >= d { | 462 | 0 | return Err(RecvTimeoutError::Timeout); | 463 | 0 | } | 464 | 1 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 1 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 1 | }); | 489 | | } | 490 | 4 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::recv <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::recv Line | Count | Source | 441 | 1.00k | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 1.00k | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 1.00k | let backoff = Backoff::new(); | 446 | 2.50k | loop { | 447 | 2.50k | if self.start_recv(token) { | 448 | | unsafe { | 449 | 1.00k | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 1.50k | } | 452 | 1.50k | | 453 | 1.50k | if backoff.is_completed() { | 454 | 0 | break; | 455 | 1.50k | } else { | 456 | 1.50k | backoff.snooze(); | 457 | 1.50k | } | 458 | | } | 459 | | | 460 | 0 | if let Some(d) = deadline { | 461 | 0 | if Instant::now() >= d { | 462 | 0 | return Err(RecvTimeoutError::Timeout); | 463 | 0 | } | 464 | 0 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 0 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 0 | }); | 489 | | } | 490 | 1.00k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::recv Line | Count | Source | 441 | 187k | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 187k | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 187k | let backoff = Backoff::new(); | 446 | 188k | loop { | 447 | 188k | if self.start_recv(token) { | 448 | | unsafe { | 449 | 193k | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 18.4E | } | 452 | 18.4E | | 453 | 18.4E | if backoff.is_completed() { | 454 | 18.4E | break; | 455 | 509 | } else { | 456 | 509 | backoff.snooze(); | 457 | 509 | } | 458 | | } | 459 | | | 460 | 18.4E | if let Some(d) = deadline { | 461 | 18.4E | if Instant::now() >= d { | 462 | 0 | return Err(RecvTimeoutError::Timeout); | 463 | 2 | } | 464 | 0 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 2 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 2 | }); | 489 | | } | 490 | 193k | } |
<crossbeam_channel::flavors::list::Channel<list::drops::DropCounter>>::recv Line | Count | Source | 441 | 471k | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 471k | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 471k | let backoff = Backoff::new(); | 446 | 472k | loop { | 447 | 472k | if self.start_recv(token) { | 448 | | unsafe { | 449 | 471k | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 955 | } | 452 | 955 | | 453 | 955 | if backoff.is_completed() { | 454 | 43 | break; | 455 | 912 | } else { | 456 | 912 | backoff.snooze(); | 457 | 912 | } | 458 | | } | 459 | | | 460 | 43 | if let Some(d0 ) = deadline { | 461 | 0 | if Instant::now() >= d { | 462 | 0 | return Err(RecvTimeoutError::Timeout); | 463 | 0 | } | 464 | 43 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 43 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 43 | }); | 489 | | } | 490 | 471k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::recv Line | Count | Source | 441 | 10.0k | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 10.0k | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 11.7k | let backoff = Backoff::new(); | 446 | 107k | loop { | 447 | 107k | if self.start_recv(token) { | 448 | | unsafe { | 449 | 10.0k | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 97.0k | } | 452 | 97.0k | | 453 | 97.0k | if backoff.is_completed() { | 454 | 1.77k | break; | 455 | 95.3k | } else { | 456 | 95.3k | backoff.snooze(); | 457 | 95.3k | } | 458 | | } | 459 | | | 460 | 1.77k | if let Some(d5 ) = deadline { | 461 | 5 | if Instant::now() >= d { | 462 | 2 | return Err(RecvTimeoutError::Timeout); | 463 | 3 | } | 464 | 1.76k | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 1.76k | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 1.76k | }); | 489 | | } | 490 | 10.0k | } |
<crossbeam_channel::flavors::list::Channel<()>>::recv Line | Count | Source | 441 | 100k | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 100k | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 100k | let backoff = Backoff::new(); | 446 | 146k | loop { | 447 | 146k | if self.start_recv(token) { | 448 | | unsafe { | 449 | 100k | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 46.7k | } | 452 | 46.7k | | 453 | 46.7k | if backoff.is_completed() { | 454 | 25 | break; | 455 | 46.7k | } else { | 456 | 46.7k | backoff.snooze(); | 457 | 46.7k | } | 458 | | } | 459 | | | 460 | 25 | if let Some(d0 ) = deadline { | 461 | 0 | if Instant::now() >= d { | 462 | 0 | return Err(RecvTimeoutError::Timeout); | 463 | 0 | } | 464 | 25 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 25 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 25 | }); | 489 | | } | 490 | 100k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<bool>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::string::String>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u8>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u32>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i64>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::recv Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::recv <crossbeam_channel::flavors::list::Channel<i32>>::recv Line | Count | Source | 441 | 8 | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 8 | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 10 | let backoff = Backoff::new(); | 446 | 32 | loop { | 447 | 32 | if self.start_recv(token) { | 448 | | unsafe { | 449 | 8 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 24 | } | 452 | 24 | | 453 | 24 | if backoff.is_completed() { | 454 | 2 | break; | 455 | 22 | } else { | 456 | 22 | backoff.snooze(); | 457 | 22 | } | 458 | | } | 459 | | | 460 | 2 | if let Some(d1 ) = deadline { | 461 | 1 | if Instant::now() >= d { | 462 | 0 | return Err(RecvTimeoutError::Timeout); | 463 | 1 | } | 464 | 1 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 2 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 2 | }); | 489 | | } | 490 | 8 | } |
<crossbeam_channel::flavors::list::Channel<()>>::recv Line | Count | Source | 441 | 7 | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 7 | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 7 | let backoff = Backoff::new(); | 446 | 17 | loop { | 447 | 17 | if self.start_recv(token) { | 448 | | unsafe { | 449 | 7 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 10 | } | 452 | 10 | | 453 | 10 | if backoff.is_completed() { | 454 | 0 | break; | 455 | 10 | } else { | 456 | 10 | backoff.snooze(); | 457 | 10 | } | 458 | | } | 459 | | | 460 | 0 | if let Some(d) = deadline { | 461 | 0 | if Instant::now() >= d { | 462 | 0 | return Err(RecvTimeoutError::Timeout); | 463 | 0 | } | 464 | 0 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 0 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 0 | }); | 489 | | } | 490 | 7 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::recv <crossbeam_channel::flavors::list::Channel<i32>>::recv Line | Count | Source | 441 | 1 | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 1 | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 2 | let backoff = Backoff::new(); | 446 | 13 | loop { | 447 | 13 | if self.start_recv(token) { | 448 | | unsafe { | 449 | 1 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 12 | } | 452 | 12 | | 453 | 12 | if backoff.is_completed() { | 454 | 1 | break; | 455 | 11 | } else { | 456 | 11 | backoff.snooze(); | 457 | 11 | } | 458 | | } | 459 | | | 460 | 1 | if let Some(d0 ) = deadline { | 461 | 0 | if Instant::now() >= d { | 462 | 0 | return Err(RecvTimeoutError::Timeout); | 463 | 0 | } | 464 | 1 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 1 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 1 | }); | 489 | | } | 490 | 1 | } |
<crossbeam_channel::flavors::list::Channel<()>>::recv Line | Count | Source | 441 | 3 | pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { | 442 | 3 | let token = &mut Token::default(); | 443 | | loop { | 444 | | // Try receiving a message several times. | 445 | 3 | let backoff = Backoff::new(); | 446 | 9 | loop { | 447 | 9 | if self.start_recv(token) { | 448 | | unsafe { | 449 | 3 | return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); | 450 | | } | 451 | 6 | } | 452 | 6 | | 453 | 6 | if backoff.is_completed() { | 454 | 0 | break; | 455 | 6 | } else { | 456 | 6 | backoff.snooze(); | 457 | 6 | } | 458 | | } | 459 | | | 460 | 0 | if let Some(d) = deadline { | 461 | 0 | if Instant::now() >= d { | 462 | 0 | return Err(RecvTimeoutError::Timeout); | 463 | 0 | } | 464 | 0 | } | 465 | | | 466 | | // Prepare for blocking until a sender wakes us up. | 467 | 0 | Context::with(|cx| { | 468 | | let oper = Operation::hook(token); | 469 | | self.receivers.register(oper, cx); | 470 | | | 471 | | // Has the channel become ready just now? | 472 | | if !self.is_empty() || self.is_disconnected() { | 473 | | let _ = cx.try_select(Selected::Aborted); | 474 | | } | 475 | | | 476 | | // Block the current thread. | 477 | | let sel = cx.wait_until(deadline); | 478 | | | 479 | | match sel { | 480 | | Selected::Waiting => unreachable!(), | 481 | | Selected::Aborted | Selected::Disconnected => { | 482 | | self.receivers.unregister(oper).unwrap(); | 483 | | // If the channel was disconnected, we still have to check for remaining | 484 | | // messages. | 485 | | } | 486 | | Selected::Operation(_) => {} | 487 | | } | 488 | 0 | }); | 489 | | } | 490 | 3 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::recv |
491 | | |
492 | | /// Returns the current number of messages inside the channel. |
493 | 110 | pub(crate) fn len(&self) -> usize { |
494 | 110 | loop { |
495 | 110 | // Load the tail index, then load the head index. |
496 | 110 | let mut tail = self.tail.index.load(Ordering::SeqCst); |
497 | 110 | let mut head = self.head.index.load(Ordering::SeqCst); |
498 | 110 | |
499 | 110 | // If the tail index didn't change, we've got consistent indices to work with. |
500 | 110 | if self.tail.index.load(Ordering::SeqCst) == tail { |
501 | | // Erase the lower bits. |
502 | 110 | tail &= !((1 << SHIFT) - 1); |
503 | 110 | head &= !((1 << SHIFT) - 1); |
504 | 110 | |
505 | 110 | // Fix up indices if they fall onto block ends. |
506 | 110 | if (tail >> SHIFT) & (LAP - 1) == LAP - 1 { |
507 | 0 | tail = tail.wrapping_add(1 << SHIFT); |
508 | 110 | } |
509 | 110 | if (head >> SHIFT) & (LAP - 1) == LAP - 1 { |
510 | 0 | head = head.wrapping_add(1 << SHIFT); |
511 | 110 | } |
512 | | |
513 | | // Rotate indices so that head falls into the first block. |
514 | 110 | let lap = (head >> SHIFT) / LAP; |
515 | 110 | tail = tail.wrapping_sub((lap * LAP) << SHIFT); |
516 | 110 | head = head.wrapping_sub((lap * LAP) << SHIFT); |
517 | 110 | |
518 | 110 | // Remove the lower bits. |
519 | 110 | tail >>= SHIFT; |
520 | 110 | head >>= SHIFT; |
521 | 110 | |
522 | 110 | // Return the difference minus the number of blocks between tail and head. |
523 | 110 | return tail - head - tail / LAP; |
524 | 0 | } |
525 | | } |
526 | 110 | } Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::len Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::len Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::len Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::len Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::len Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::len Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::len <crossbeam_channel::flavors::list::Channel<usize>>::len Line | Count | Source | 493 | 104 | pub(crate) fn len(&self) -> usize { | 494 | 104 | loop { | 495 | 104 | // Load the tail index, then load the head index. | 496 | 104 | let mut tail = self.tail.index.load(Ordering::SeqCst); | 497 | 104 | let mut head = self.head.index.load(Ordering::SeqCst); | 498 | 104 | | 499 | 104 | // If the tail index didn't change, we've got consistent indices to work with. | 500 | 104 | if self.tail.index.load(Ordering::SeqCst) == tail { | 501 | | // Erase the lower bits. | 502 | 104 | tail &= !((1 << SHIFT) - 1); | 503 | 104 | head &= !((1 << SHIFT) - 1); | 504 | 104 | | 505 | 104 | // Fix up indices if they fall onto block ends. | 506 | 104 | if (tail >> SHIFT) & (LAP - 1) == LAP - 1 { | 507 | 0 | tail = tail.wrapping_add(1 << SHIFT); | 508 | 104 | } | 509 | 104 | if (head >> SHIFT) & (LAP - 1) == LAP - 1 { | 510 | 0 | head = head.wrapping_add(1 << SHIFT); | 511 | 104 | } | 512 | | | 513 | | // Rotate indices so that head falls into the first block. | 514 | 104 | let lap = (head >> SHIFT) / LAP; | 515 | 104 | tail = tail.wrapping_sub((lap * LAP) << SHIFT); | 516 | 104 | head = head.wrapping_sub((lap * LAP) << SHIFT); | 517 | 104 | | 518 | 104 | // Remove the lower bits. | 519 | 104 | tail >>= SHIFT; | 520 | 104 | head >>= SHIFT; | 521 | 104 | | 522 | 104 | // Return the difference minus the number of blocks between tail and head. | 523 | 104 | return tail - head - tail / LAP; | 524 | 0 | } | 525 | | } | 526 | 104 | } |
<crossbeam_channel::flavors::list::Channel<()>>::len Line | Count | Source | 493 | 6 | pub(crate) fn len(&self) -> usize { | 494 | 6 | loop { | 495 | 6 | // Load the tail index, then load the head index. | 496 | 6 | let mut tail = self.tail.index.load(Ordering::SeqCst); | 497 | 6 | let mut head = self.head.index.load(Ordering::SeqCst); | 498 | 6 | | 499 | 6 | // If the tail index didn't change, we've got consistent indices to work with. | 500 | 6 | if self.tail.index.load(Ordering::SeqCst) == tail { | 501 | | // Erase the lower bits. | 502 | 6 | tail &= !((1 << SHIFT) - 1); | 503 | 6 | head &= !((1 << SHIFT) - 1); | 504 | 6 | | 505 | 6 | // Fix up indices if they fall onto block ends. | 506 | 6 | if (tail >> SHIFT) & (LAP - 1) == LAP - 1 { | 507 | 0 | tail = tail.wrapping_add(1 << SHIFT); | 508 | 6 | } | 509 | 6 | if (head >> SHIFT) & (LAP - 1) == LAP - 1 { | 510 | 0 | head = head.wrapping_add(1 << SHIFT); | 511 | 6 | } | 512 | | | 513 | | // Rotate indices so that head falls into the first block. | 514 | 6 | let lap = (head >> SHIFT) / LAP; | 515 | 6 | tail = tail.wrapping_sub((lap * LAP) << SHIFT); | 516 | 6 | head = head.wrapping_sub((lap * LAP) << SHIFT); | 517 | 6 | | 518 | 6 | // Remove the lower bits. | 519 | 6 | tail >>= SHIFT; | 520 | 6 | head >>= SHIFT; | 521 | 6 | | 522 | 6 | // Return the difference minus the number of blocks between tail and head. | 523 | 6 | return tail - head - tail / LAP; | 524 | 0 | } | 525 | | } | 526 | 6 | } |
|
527 | | |
528 | | /// Returns the capacity of the channel. |
529 | 2 | pub(crate) fn capacity(&self) -> Option<usize> { |
530 | 2 | None |
531 | 2 | } |
532 | | |
533 | | /// Disconnects the channel and wakes up all blocked receivers. |
534 | | /// |
535 | | /// Returns `true` if this call disconnected the channel. |
536 | 22.7k | pub(crate) fn disconnect(&self) -> bool { |
537 | 22.7k | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); |
538 | 22.7k | |
539 | 22.7k | if tail & MARK_BIT == 0 { |
540 | 11.3k | self.receivers.disconnect(); |
541 | 11.3k | true |
542 | | } else { |
543 | 11.3k | false |
544 | | } |
545 | 22.7k | } Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<zero::drops::DropCounter>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::disconnect <crossbeam_channel::flavors::list::Channel<()>>::disconnect Line | Count | Source | 536 | 18 | pub(crate) fn disconnect(&self) -> bool { | 537 | 18 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 18 | | 539 | 18 | if tail & MARK_BIT == 0 { | 540 | 9 | self.receivers.disconnect(); | 541 | 9 | true | 542 | | } else { | 543 | 9 | false | 544 | | } | 545 | 18 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::disconnect Line | Count | Source | 536 | 46 | pub(crate) fn disconnect(&self) -> bool { | 537 | 46 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 46 | | 539 | 46 | if tail & MARK_BIT == 0 { | 540 | 23 | self.receivers.disconnect(); | 541 | 23 | true | 542 | | } else { | 543 | 23 | false | 544 | | } | 545 | 46 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::disconnect Line | Count | Source | 536 | 6 | pub(crate) fn disconnect(&self) -> bool { | 537 | 6 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 6 | | 539 | 6 | if tail & MARK_BIT == 0 { | 540 | 3 | self.receivers.disconnect(); | 541 | 3 | true | 542 | | } else { | 543 | 3 | false | 544 | | } | 545 | 6 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::disconnect <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<isize>>>::disconnect Line | Count | Source | 536 | 6 | pub(crate) fn disconnect(&self) -> bool { | 537 | 6 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 6 | | 539 | 6 | if tail & MARK_BIT == 0 { | 540 | 3 | self.receivers.disconnect(); | 541 | 3 | true | 542 | | } else { | 543 | 3 | false | 544 | | } | 545 | 6 | } |
<crossbeam_channel::flavors::list::Channel<()>>::disconnect Line | Count | Source | 536 | 70 | pub(crate) fn disconnect(&self) -> bool { | 537 | 70 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 70 | | 539 | 70 | if tail & MARK_BIT == 0 { | 540 | 35 | self.receivers.disconnect(); | 541 | 35 | true | 542 | | } else { | 543 | 35 | false | 544 | | } | 545 | 70 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::disconnect Line | Count | Source | 536 | 118 | pub(crate) fn disconnect(&self) -> bool { | 537 | 118 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 118 | | 539 | 118 | if tail & MARK_BIT == 0 { | 540 | 59 | self.receivers.disconnect(); | 541 | 59 | true | 542 | | } else { | 543 | 59 | false | 544 | | } | 545 | 118 | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<i32>>>::disconnect Line | Count | Source | 536 | 10 | pub(crate) fn disconnect(&self) -> bool { | 537 | 10 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 10 | | 539 | 10 | if tail & MARK_BIT == 0 { | 540 | 5 | self.receivers.disconnect(); | 541 | 5 | true | 542 | | } else { | 543 | 5 | false | 544 | | } | 545 | 10 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::disconnect Line | Count | Source | 536 | 4 | pub(crate) fn disconnect(&self) -> bool { | 537 | 4 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 4 | | 539 | 4 | if tail & MARK_BIT == 0 { | 540 | 2 | self.receivers.disconnect(); | 541 | 2 | true | 542 | | } else { | 543 | 2 | false | 544 | | } | 545 | 4 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<array::drops::DropCounter>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::disconnect <crossbeam_channel::flavors::list::Channel<()>>::disconnect Line | Count | Source | 536 | 2 | pub(crate) fn disconnect(&self) -> bool { | 537 | 2 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 2 | | 539 | 2 | if tail & MARK_BIT == 0 { | 540 | 1 | self.receivers.disconnect(); | 541 | 1 | true | 542 | | } else { | 543 | 1 | false | 544 | | } | 545 | 2 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::disconnect Line | Count | Source | 536 | 14 | pub(crate) fn disconnect(&self) -> bool { | 537 | 14 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 14 | | 539 | 14 | if tail & MARK_BIT == 0 { | 540 | 7 | self.receivers.disconnect(); | 541 | 7 | true | 542 | | } else { | 543 | 7 | false | 544 | | } | 545 | 14 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::disconnect <crossbeam_channel::flavors::list::Channel<i32>>::disconnect Line | Count | Source | 536 | 2 | pub(crate) fn disconnect(&self) -> bool { | 537 | 2 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 2 | | 539 | 2 | if tail & MARK_BIT == 0 { | 540 | 1 | self.receivers.disconnect(); | 541 | 1 | true | 542 | | } else { | 543 | 1 | false | 544 | | } | 545 | 2 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::disconnect <crossbeam_channel::flavors::list::Channel<usize>>::disconnect Line | Count | Source | 536 | 6 | pub(crate) fn disconnect(&self) -> bool { | 537 | 6 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 6 | | 539 | 6 | if tail & MARK_BIT == 0 { | 540 | 3 | self.receivers.disconnect(); | 541 | 3 | true | 542 | | } else { | 543 | 3 | false | 544 | | } | 545 | 6 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::disconnect <crossbeam_channel::flavors::list::Channel<()>>::disconnect Line | Count | Source | 536 | 16 | pub(crate) fn disconnect(&self) -> bool { | 537 | 16 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 16 | | 539 | 16 | if tail & MARK_BIT == 0 { | 540 | 8 | self.receivers.disconnect(); | 541 | 8 | true | 542 | | } else { | 543 | 8 | false | 544 | | } | 545 | 16 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::disconnect Line | Count | Source | 536 | 20.0k | pub(crate) fn disconnect(&self) -> bool { | 537 | 20.0k | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 20.0k | | 539 | 20.0k | if tail & MARK_BIT == 0 { | 540 | 10.0k | self.receivers.disconnect(); | 541 | 10.0k | true | 542 | | } else { | 543 | 10.0k | false | 544 | | } | 545 | 20.0k | } |
<crossbeam_channel::flavors::list::Channel<list::drops::DropCounter>>::disconnect Line | Count | Source | 536 | 200 | pub(crate) fn disconnect(&self) -> bool { | 537 | 200 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 200 | | 539 | 200 | if tail & MARK_BIT == 0 { | 540 | 100 | self.receivers.disconnect(); | 541 | 100 | true | 542 | | } else { | 543 | 100 | false | 544 | | } | 545 | 200 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::disconnect Line | Count | Source | 536 | 10 | pub(crate) fn disconnect(&self) -> bool { | 537 | 10 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 10 | | 539 | 10 | if tail & MARK_BIT == 0 { | 540 | 5 | self.receivers.disconnect(); | 541 | 5 | true | 542 | | } else { | 543 | 5 | false | 544 | | } | 545 | 10 | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::disconnect Line | Count | Source | 536 | 2.00k | pub(crate) fn disconnect(&self) -> bool { | 537 | 2.00k | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 2.00k | | 539 | 2.00k | if tail & MARK_BIT == 0 { | 540 | 1.00k | self.receivers.disconnect(); | 541 | 1.00k | true | 542 | | } else { | 543 | 1.00k | false | 544 | | } | 545 | 2.00k | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i64>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u32>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any>>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u8>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<[u8; 0]>>::disconnect <crossbeam_channel::flavors::list::Channel<i32>>::disconnect Line | Count | Source | 536 | 4 | pub(crate) fn disconnect(&self) -> bool { | 537 | 4 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 4 | | 539 | 4 | if tail & MARK_BIT == 0 { | 540 | 2 | self.receivers.disconnect(); | 541 | 2 | true | 542 | | } else { | 543 | 2 | false | 544 | | } | 545 | 4 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<golang::zerosize::zero_size_struct::ZeroSize>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::string::String>>::disconnect Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<bool>>::disconnect <crossbeam_channel::flavors::list::Channel<()>>::disconnect Line | Count | Source | 536 | 26 | pub(crate) fn disconnect(&self) -> bool { | 537 | 26 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 26 | | 539 | 26 | if tail & MARK_BIT == 0 { | 540 | 13 | self.receivers.disconnect(); | 541 | 13 | true | 542 | | } else { | 543 | 13 | false | 544 | | } | 545 | 26 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::disconnect <crossbeam_channel::flavors::list::Channel<i32>>::disconnect Line | Count | Source | 536 | 66 | pub(crate) fn disconnect(&self) -> bool { | 537 | 66 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 66 | | 539 | 66 | if tail & MARK_BIT == 0 { | 540 | 33 | self.receivers.disconnect(); | 541 | 33 | true | 542 | | } else { | 543 | 33 | false | 544 | | } | 545 | 66 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::disconnect <crossbeam_channel::flavors::list::Channel<usize>>::disconnect Line | Count | Source | 536 | 6 | pub(crate) fn disconnect(&self) -> bool { | 537 | 6 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 6 | | 539 | 6 | if tail & MARK_BIT == 0 { | 540 | 3 | self.receivers.disconnect(); | 541 | 3 | true | 542 | | } else { | 543 | 3 | false | 544 | | } | 545 | 6 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant>>::disconnect <crossbeam_channel::flavors::list::Channel<i32>>::disconnect Line | Count | Source | 536 | 38 | pub(crate) fn disconnect(&self) -> bool { | 537 | 38 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 38 | | 539 | 38 | if tail & MARK_BIT == 0 { | 540 | 19 | self.receivers.disconnect(); | 541 | 19 | true | 542 | | } else { | 543 | 19 | false | 544 | | } | 545 | 38 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>>>::disconnect <crossbeam_channel::flavors::list::Channel<usize>>::disconnect Line | Count | Source | 536 | 6 | pub(crate) fn disconnect(&self) -> bool { | 537 | 6 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 6 | | 539 | 6 | if tail & MARK_BIT == 0 { | 540 | 3 | self.receivers.disconnect(); | 541 | 3 | true | 542 | | } else { | 543 | 3 | false | 544 | | } | 545 | 6 | } |
<crossbeam_channel::flavors::list::Channel<()>>::disconnect Line | Count | Source | 536 | 18 | pub(crate) fn disconnect(&self) -> bool { | 537 | 18 | let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); | 538 | 18 | | 539 | 18 | if tail & MARK_BIT == 0 { | 540 | 9 | self.receivers.disconnect(); | 541 | 9 | true | 542 | | } else { | 543 | 9 | false | 544 | | } | 545 | 18 | } |
|
546 | | |
547 | | /// Returns `true` if the channel is disconnected. |
548 | 38.7k | pub(crate) fn is_disconnected(&self) -> bool { |
549 | 38.7k | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 |
550 | 38.7k | } <crossbeam_channel::flavors::list::Channel<i32>>::is_disconnected Line | Count | Source | 548 | 12 | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 12 | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 12 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::is_disconnected Line | Count | Source | 548 | 266 | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 266 | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 266 | } |
<crossbeam_channel::flavors::list::Channel<()>>::is_disconnected Line | Count | Source | 548 | 39 | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 39 | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 39 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::is_disconnected Line | Count | Source | 548 | 6.29k | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 6.29k | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 6.29k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::is_disconnected Line | Count | Source | 548 | 218 | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 218 | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 218 | } |
<crossbeam_channel::flavors::list::Channel<()>>::is_disconnected Line | Count | Source | 548 | 9 | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 9 | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 9 | } |
<crossbeam_channel::flavors::list::Channel<()>>::is_disconnected Line | Count | Source | 548 | 1 | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 1 | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 1 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::is_disconnected Line | Count | Source | 548 | 1 | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 1 | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 1 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::is_disconnected Line | Count | Source | 548 | 2 | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 2 | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 2 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::is_disconnected Line | Count | Source | 548 | 272 | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 272 | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 272 | } |
<crossbeam_channel::flavors::list::Channel<list::drops::DropCounter>>::is_disconnected Line | Count | Source | 548 | 9 | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 9 | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 9 | } |
<crossbeam_channel::flavors::list::Channel<()>>::is_disconnected Line | Count | Source | 548 | 11 | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 11 | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 11 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::is_disconnected Line | Count | Source | 548 | 4 | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 4 | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 4 | } |
<crossbeam_channel::flavors::list::Channel<()>>::is_disconnected Line | Count | Source | 548 | 141 | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 141 | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 141 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::is_disconnected Line | Count | Source | 548 | 2.12k | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 2.12k | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 2.12k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::is_disconnected Line | Count | Source | 548 | 11 | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 11 | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 11 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::is_disconnected Line | Count | Source | 548 | 149 | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 149 | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 149 | } |
<crossbeam_channel::flavors::list::Channel<()>>::is_disconnected Line | Count | Source | 548 | 23.2k | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 23.2k | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 23.2k | } |
<crossbeam_channel::flavors::list::Channel<usize>>::is_disconnected Line | Count | Source | 548 | 5.89k | pub(crate) fn is_disconnected(&self) -> bool { | 549 | 5.89k | self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 | 550 | 5.89k | } |
|
551 | | |
552 | | /// Returns `true` if the channel is empty. |
553 | 222k | pub(crate) fn is_empty(&self) -> bool { |
554 | 222k | let head = self.head.index.load(Ordering::SeqCst); |
555 | 222k | let tail = self.tail.index.load(Ordering::SeqCst); |
556 | 222k | head >> SHIFT == tail >> SHIFT |
557 | 222k | } <crossbeam_channel::flavors::list::Channel<()>>::is_empty Line | Count | Source | 553 | 10.1k | pub(crate) fn is_empty(&self) -> bool { | 554 | 10.1k | let head = self.head.index.load(Ordering::SeqCst); | 555 | 10.1k | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 10.1k | head >> SHIFT == tail >> SHIFT | 557 | 10.1k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::is_empty Line | Count | Source | 553 | 12 | pub(crate) fn is_empty(&self) -> bool { | 554 | 12 | let head = self.head.index.load(Ordering::SeqCst); | 555 | 12 | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 12 | head >> SHIFT == tail >> SHIFT | 557 | 12 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::is_empty Line | Count | Source | 553 | 517 | pub(crate) fn is_empty(&self) -> bool { | 554 | 517 | let head = self.head.index.load(Ordering::SeqCst); | 555 | 517 | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 517 | head >> SHIFT == tail >> SHIFT | 557 | 517 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::is_empty Line | Count | Source | 553 | 218 | pub(crate) fn is_empty(&self) -> bool { | 554 | 218 | let head = self.head.index.load(Ordering::SeqCst); | 555 | 218 | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 218 | head >> SHIFT == tail >> SHIFT | 557 | 218 | } |
<crossbeam_channel::flavors::list::Channel<()>>::is_empty Line | Count | Source | 553 | 10 | pub(crate) fn is_empty(&self) -> bool { | 554 | 10 | let head = self.head.index.load(Ordering::SeqCst); | 555 | 10 | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 10 | head >> SHIFT == tail >> SHIFT | 557 | 10 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::is_empty Line | Count | Source | 553 | 11.9k | pub(crate) fn is_empty(&self) -> bool { | 554 | 11.9k | let head = self.head.index.load(Ordering::SeqCst); | 555 | 11.9k | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 11.9k | head >> SHIFT == tail >> SHIFT | 557 | 11.9k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::is_empty Line | Count | Source | 553 | 1 | pub(crate) fn is_empty(&self) -> bool { | 554 | 1 | let head = self.head.index.load(Ordering::SeqCst); | 555 | 1 | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 1 | head >> SHIFT == tail >> SHIFT | 557 | 1 | } |
<crossbeam_channel::flavors::list::Channel<()>>::is_empty Line | Count | Source | 553 | 1 | pub(crate) fn is_empty(&self) -> bool { | 554 | 1 | let head = self.head.index.load(Ordering::SeqCst); | 555 | 1 | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 1 | head >> SHIFT == tail >> SHIFT | 557 | 1 | } |
<crossbeam_channel::flavors::list::Channel<list::drops::DropCounter>>::is_empty Line | Count | Source | 553 | 43 | pub(crate) fn is_empty(&self) -> bool { | 554 | 43 | let head = self.head.index.load(Ordering::SeqCst); | 555 | 43 | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 43 | head >> SHIFT == tail >> SHIFT | 557 | 43 | } |
<crossbeam_channel::flavors::list::Channel<()>>::is_empty Line | Count | Source | 553 | 31 | pub(crate) fn is_empty(&self) -> bool { | 554 | 31 | let head = self.head.index.load(Ordering::SeqCst); | 555 | 31 | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 31 | head >> SHIFT == tail >> SHIFT | 557 | 31 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::is_empty Line | Count | Source | 553 | 2 | pub(crate) fn is_empty(&self) -> bool { | 554 | 2 | let head = self.head.index.load(Ordering::SeqCst); | 555 | 2 | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 2 | head >> SHIFT == tail >> SHIFT | 557 | 2 | } |
<crossbeam_channel::flavors::list::Channel<i32>>::is_empty Line | Count | Source | 553 | 1.76k | pub(crate) fn is_empty(&self) -> bool { | 554 | 1.76k | let head = self.head.index.load(Ordering::SeqCst); | 555 | 1.76k | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 1.76k | head >> SHIFT == tail >> SHIFT | 557 | 1.76k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::is_empty Line | Count | Source | 553 | 4 | pub(crate) fn is_empty(&self) -> bool { | 554 | 4 | let head = self.head.index.load(Ordering::SeqCst); | 555 | 4 | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 4 | head >> SHIFT == tail >> SHIFT | 557 | 4 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::is_empty Line | Count | Source | 553 | 5.64k | pub(crate) fn is_empty(&self) -> bool { | 554 | 5.64k | let head = self.head.index.load(Ordering::SeqCst); | 555 | 5.64k | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 5.64k | head >> SHIFT == tail >> SHIFT | 557 | 5.64k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::is_empty Line | Count | Source | 553 | 11 | pub(crate) fn is_empty(&self) -> bool { | 554 | 11 | let head = self.head.index.load(Ordering::SeqCst); | 555 | 11 | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 11 | head >> SHIFT == tail >> SHIFT | 557 | 11 | } |
<crossbeam_channel::flavors::list::Channel<()>>::is_empty Line | Count | Source | 553 | 10.3k | pub(crate) fn is_empty(&self) -> bool { | 554 | 10.3k | let head = self.head.index.load(Ordering::SeqCst); | 555 | 10.3k | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 10.3k | head >> SHIFT == tail >> SHIFT | 557 | 10.3k | } |
<crossbeam_channel::flavors::list::Channel<i32>>::is_empty Line | Count | Source | 553 | 157 | pub(crate) fn is_empty(&self) -> bool { | 554 | 157 | let head = self.head.index.load(Ordering::SeqCst); | 555 | 157 | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 157 | head >> SHIFT == tail >> SHIFT | 557 | 157 | } |
<crossbeam_channel::flavors::list::Channel<usize>>::is_empty Line | Count | Source | 553 | 15.8k | pub(crate) fn is_empty(&self) -> bool { | 554 | 15.8k | let head = self.head.index.load(Ordering::SeqCst); | 555 | 15.8k | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 15.8k | head >> SHIFT == tail >> SHIFT | 557 | 15.8k | } |
<crossbeam_channel::flavors::list::Channel<()>>::is_empty Line | Count | Source | 553 | 165k | pub(crate) fn is_empty(&self) -> bool { | 554 | 165k | let head = self.head.index.load(Ordering::SeqCst); | 555 | 165k | let tail = self.tail.index.load(Ordering::SeqCst); | 556 | 165k | head >> SHIFT == tail >> SHIFT | 557 | 165k | } |
|
558 | | |
559 | | /// Returns `true` if the channel is full. |
560 | 6 | pub(crate) fn is_full(&self) -> bool { |
561 | 6 | false |
562 | 6 | } |
563 | | } |
564 | | |
565 | | impl<T> Drop for Channel<T> { |
566 | 11.3k | fn drop(&mut self) { |
567 | 11.3k | let mut head = self.head.index.load(Ordering::Relaxed); |
568 | 11.3k | let mut tail = self.tail.index.load(Ordering::Relaxed); |
569 | 11.3k | let mut block = self.head.block.load(Ordering::Relaxed); |
570 | 11.3k | |
571 | 11.3k | // Erase the lower bits. |
572 | 11.3k | head &= !((1 << SHIFT) - 1); |
573 | 11.3k | tail &= !((1 << SHIFT) - 1); |
574 | | |
575 | | unsafe { |
576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. |
577 | 115k | while head != tail { |
578 | 104k | let offset = (head >> SHIFT) % LAP; |
579 | 104k | |
580 | 104k | if offset < BLOCK_CAP { |
581 | 101k | // Drop the message in the slot. |
582 | 101k | let slot = (*block).slots.get_unchecked(offset); |
583 | 101k | let p = &mut *slot.msg.get(); |
584 | 101k | p.as_mut_ptr().drop_in_place(); |
585 | 101k | } else { |
586 | 3.25k | // Deallocate the block and move to the next one. |
587 | 3.25k | let next = (*block).next.load(Ordering::Relaxed); |
588 | 3.25k | drop(Box::from_raw(block)); |
589 | 3.25k | block = next; |
590 | 3.25k | } |
591 | | |
592 | 104k | head = head.wrapping_add(1 << SHIFT); |
593 | | } |
594 | | |
595 | | // Deallocate the last remaining block. |
596 | 11.3k | if !block.is_null() { |
597 | 11.2k | drop(Box::from_raw(block)); |
598 | 11.2k | }81 |
599 | | } |
600 | 11.3k | } Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<zero::drops::DropCounter> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize> as core::ops::drop::Drop>::drop <crossbeam_channel::flavors::list::Channel<usize> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 3 | fn drop(&mut self) { | 567 | 3 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 3 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 3 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 3 | | 571 | 3 | // Erase the lower bits. | 572 | 3 | head &= !((1 << SHIFT) - 1); | 573 | 3 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 3 | while head != tail { | 578 | 0 | let offset = (head >> SHIFT) % LAP; | 579 | 0 |
| 580 | 0 | if offset < BLOCK_CAP { | 581 | 0 | // Drop the message in the slot. | 582 | 0 | let slot = (*block).slots.get_unchecked(offset); | 583 | 0 | let p = &mut *slot.msg.get(); | 584 | 0 | p.as_mut_ptr().drop_in_place(); | 585 | 0 | } else { | 586 | 0 | // Deallocate the block and move to the next one. | 587 | 0 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 0 | drop(Box::from_raw(block)); | 589 | 0 | block = next; | 590 | 0 | } | 591 | | | 592 | 0 | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 3 | if !block.is_null() { | 597 | 3 | drop(Box::from_raw(block)); | 598 | 3 | }0 | 599 | | } | 600 | 3 | } |
<crossbeam_channel::flavors::list::Channel<()> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 9 | fn drop(&mut self) { | 567 | 9 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 9 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 9 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 9 | | 571 | 9 | // Erase the lower bits. | 572 | 9 | head &= !((1 << SHIFT) - 1); | 573 | 9 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 7.80k | while head != tail { | 578 | 7.79k | let offset = (head >> SHIFT) % LAP; | 579 | 7.79k | | 580 | 7.79k | if offset < BLOCK_CAP { | 581 | 7.54k | // Drop the message in the slot. | 582 | 7.54k | let slot = (*block).slots.get_unchecked(offset); | 583 | 7.54k | let p = &mut *slot.msg.get(); | 584 | 7.54k | p.as_mut_ptr().drop_in_place(); | 585 | 7.54k | } else { | 586 | 243 | // Deallocate the block and move to the next one. | 587 | 243 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 243 | drop(Box::from_raw(block)); | 589 | 243 | block = next; | 590 | 243 | } | 591 | | | 592 | 7.79k | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 9 | if !block.is_null() { | 597 | 7 | drop(Box::from_raw(block)); | 598 | 7 | }2 | 599 | | } | 600 | 9 | } |
<crossbeam_channel::flavors::list::Channel<i32> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 23 | fn drop(&mut self) { | 567 | 23 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 23 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 23 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 23 | | 571 | 23 | // Erase the lower bits. | 572 | 23 | head &= !((1 << SHIFT) - 1); | 573 | 23 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 26 | while head != tail { | 578 | 3 | let offset = (head >> SHIFT) % LAP; | 579 | 3 | | 580 | 3 | if offset < BLOCK_CAP { | 581 | 3 | // Drop the message in the slot. | 582 | 3 | let slot = (*block).slots.get_unchecked(offset); | 583 | 3 | let p = &mut *slot.msg.get(); | 584 | 3 | p.as_mut_ptr().drop_in_place(); | 585 | 3 | } else { | 586 | 0 | // Deallocate the block and move to the next one. | 587 | 0 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 0 | drop(Box::from_raw(block)); | 589 | 0 | block = next; | 590 | 0 | } | 591 | | | 592 | 3 | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 23 | if !block.is_null() { | 597 | 12 | drop(Box::from_raw(block)); | 598 | 12 | }11 | 599 | | } | 600 | 23 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant> as core::ops::drop::Drop>::drop <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<isize>> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 3 | fn drop(&mut self) { | 567 | 3 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 3 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 3 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 3 | | 571 | 3 | // Erase the lower bits. | 572 | 3 | head &= !((1 << SHIFT) - 1); | 573 | 3 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 5 | while head != tail { | 578 | 2 | let offset = (head >> SHIFT) % LAP; | 579 | 2 | | 580 | 2 | if offset < BLOCK_CAP { | 581 | 2 | // Drop the message in the slot. | 582 | 2 | let slot = (*block).slots.get_unchecked(offset); | 583 | 2 | let p = &mut *slot.msg.get(); | 584 | 2 | p.as_mut_ptr().drop_in_place(); | 585 | 2 | } else { | 586 | 0 | // Deallocate the block and move to the next one. | 587 | 0 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 0 | drop(Box::from_raw(block)); | 589 | 0 | block = next; | 590 | 0 | } | 591 | | | 592 | 2 | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 3 | if !block.is_null() { | 597 | 3 | drop(Box::from_raw(block)); | 598 | 3 | }0 | 599 | | } | 600 | 3 | } |
<crossbeam_channel::flavors::list::Channel<()> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 35 | fn drop(&mut self) { | 567 | 35 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 35 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 35 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 35 | | 571 | 35 | // Erase the lower bits. | 572 | 35 | head &= !((1 << SHIFT) - 1); | 573 | 35 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 1.68k | while head != tail { | 578 | 1.65k | let offset = (head >> SHIFT) % LAP; | 579 | 1.65k | | 580 | 1.65k | if offset < BLOCK_CAP { | 581 | 1.60k | // Drop the message in the slot. | 582 | 1.60k | let slot = (*block).slots.get_unchecked(offset); | 583 | 1.60k | let p = &mut *slot.msg.get(); | 584 | 1.60k | p.as_mut_ptr().drop_in_place(); | 585 | 1.60k | } else { | 586 | 51 | // Deallocate the block and move to the next one. | 587 | 51 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 51 | drop(Box::from_raw(block)); | 589 | 51 | block = next; | 590 | 51 | } | 591 | | | 592 | 1.65k | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 34 | if !block.is_null() { | 597 | 30 | drop(Box::from_raw(block)); | 598 | 30 | }4 | 599 | | } | 600 | 34 | } |
<crossbeam_channel::flavors::list::Channel<i32> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 59 | fn drop(&mut self) { | 567 | 59 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 59 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 59 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 59 | | 571 | 59 | // Erase the lower bits. | 572 | 59 | head &= !((1 << SHIFT) - 1); | 573 | 59 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 2.39k | while head != tail { | 578 | 2.33k | let offset = (head >> SHIFT) % LAP; | 579 | 2.33k | | 580 | 2.33k | if offset < BLOCK_CAP { | 581 | 2.26k | // Drop the message in the slot. | 582 | 2.26k | let slot = (*block).slots.get_unchecked(offset); | 583 | 2.26k | let p = &mut *slot.msg.get(); | 584 | 2.26k | p.as_mut_ptr().drop_in_place(); | 585 | 2.26k | } else { | 586 | 75 | // Deallocate the block and move to the next one. | 587 | 75 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 75 | drop(Box::from_raw(block)); | 589 | 75 | block = next; | 590 | 75 | } | 591 | | | 592 | 2.33k | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 59 | if !block.is_null() { | 597 | 35 | drop(Box::from_raw(block)); | 598 | 35 | }24 | 599 | | } | 600 | 59 | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<i32>> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 5 | fn drop(&mut self) { | 567 | 5 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 5 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 5 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 5 | | 571 | 5 | // Erase the lower bits. | 572 | 5 | head &= !((1 << SHIFT) - 1); | 573 | 5 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 5 | while head != tail { | 578 | 0 | let offset = (head >> SHIFT) % LAP; | 579 | 0 |
| 580 | 0 | if offset < BLOCK_CAP { | 581 | 0 | // Drop the message in the slot. | 582 | 0 | let slot = (*block).slots.get_unchecked(offset); | 583 | 0 | let p = &mut *slot.msg.get(); | 584 | 0 | p.as_mut_ptr().drop_in_place(); | 585 | 0 | } else { | 586 | 0 | // Deallocate the block and move to the next one. | 587 | 0 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 0 | drop(Box::from_raw(block)); | 589 | 0 | block = next; | 590 | 0 | } | 591 | | | 592 | 0 | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 5 | if !block.is_null() { | 597 | 3 | drop(Box::from_raw(block)); | 598 | 3 | }2 | 599 | | } | 600 | 5 | } |
<crossbeam_channel::flavors::list::Channel<usize> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 2 | fn drop(&mut self) { | 567 | 2 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 2 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 2 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 2 | | 571 | 2 | // Erase the lower bits. | 572 | 2 | head &= !((1 << SHIFT) - 1); | 573 | 2 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 2 | while head != tail { | 578 | 0 | let offset = (head >> SHIFT) % LAP; | 579 | 0 |
| 580 | 0 | if offset < BLOCK_CAP { | 581 | 0 | // Drop the message in the slot. | 582 | 0 | let slot = (*block).slots.get_unchecked(offset); | 583 | 0 | let p = &mut *slot.msg.get(); | 584 | 0 | p.as_mut_ptr().drop_in_place(); | 585 | 0 | } else { | 586 | 0 | // Deallocate the block and move to the next one. | 587 | 0 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 0 | drop(Box::from_raw(block)); | 589 | 0 | block = next; | 590 | 0 | } | 591 | | | 592 | 0 | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 2 | if !block.is_null() { | 597 | 2 | drop(Box::from_raw(block)); | 598 | 2 | }0 | 599 | | } | 600 | 2 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<array::drops::DropCounter> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()> as core::ops::drop::Drop>::drop <crossbeam_channel::flavors::list::Channel<i32> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 7 | fn drop(&mut self) { | 567 | 7 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 7 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 7 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 7 | | 571 | 7 | // Erase the lower bits. | 572 | 7 | head &= !((1 << SHIFT) - 1); | 573 | 7 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 8 | while head != tail { | 578 | 2 | let offset = (head >> SHIFT) % LAP; | 579 | 2 | | 580 | 2 | if offset < BLOCK_CAP { | 581 | 1 | // Drop the message in the slot. | 582 | 1 | let slot = (*block).slots.get_unchecked(offset); | 583 | 1 | let p = &mut *slot.msg.get(); | 584 | 1 | p.as_mut_ptr().drop_in_place(); | 585 | 1 | } else { | 586 | 0 | // Deallocate the block and move to the next one. | 587 | 0 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 0 | drop(Box::from_raw(block)); | 589 | 0 | block = next; | 590 | 0 | } | 591 | | | 592 | 1 | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 6 | if !block.is_null() { | 597 | 6 | drop(Box::from_raw(block)); | 598 | 6 | }0 | 599 | | } | 600 | 6 | } |
<crossbeam_channel::flavors::list::Channel<()> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 1 | fn drop(&mut self) { | 567 | 1 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 1 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 1 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 1 | | 571 | 1 | // Erase the lower bits. | 572 | 1 | head &= !((1 << SHIFT) - 1); | 573 | 1 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 46 | while head != tail { | 578 | 45 | let offset = (head >> SHIFT) % LAP; | 579 | 45 | | 580 | 45 | if offset < BLOCK_CAP { | 581 | 44 | // Drop the message in the slot. | 582 | 44 | let slot = (*block).slots.get_unchecked(offset); | 583 | 44 | let p = &mut *slot.msg.get(); | 584 | 44 | p.as_mut_ptr().drop_in_place(); | 585 | 44 | } else { | 586 | 1 | // Deallocate the block and move to the next one. | 587 | 1 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 1 | drop(Box::from_raw(block)); | 589 | 1 | block = next; | 590 | 1 | } | 591 | | | 592 | 45 | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 1 | if !block.is_null() { | 597 | 1 | drop(Box::from_raw(block)); | 598 | 1 | }0 | 599 | | } | 600 | 1 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant> as core::ops::drop::Drop>::drop <crossbeam_channel::flavors::list::Channel<i32> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 1 | fn drop(&mut self) { | 567 | 1 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 1 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 1 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 1 | | 571 | 1 | // Erase the lower bits. | 572 | 1 | head &= !((1 << SHIFT) - 1); | 573 | 1 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 2 | while head != tail { | 578 | 1 | let offset = (head >> SHIFT) % LAP; | 579 | 1 | | 580 | 1 | if offset < BLOCK_CAP { | 581 | 1 | // Drop the message in the slot. | 582 | 1 | let slot = (*block).slots.get_unchecked(offset); | 583 | 1 | let p = &mut *slot.msg.get(); | 584 | 1 | p.as_mut_ptr().drop_in_place(); | 585 | 1 | } else { | 586 | 0 | // Deallocate the block and move to the next one. | 587 | 0 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 0 | drop(Box::from_raw(block)); | 589 | 0 | block = next; | 590 | 0 | } | 591 | | | 592 | 1 | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 1 | if !block.is_null() { | 597 | 1 | drop(Box::from_raw(block)); | 598 | 1 | }0 | 599 | | } | 600 | 1 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant> as core::ops::drop::Drop>::drop <crossbeam_channel::flavors::list::Channel<usize> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 3 | fn drop(&mut self) { | 567 | 3 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 3 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 3 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 3 | | 571 | 3 | // Erase the lower bits. | 572 | 3 | head &= !((1 << SHIFT) - 1); | 573 | 3 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 3 | while head != tail { | 578 | 0 | let offset = (head >> SHIFT) % LAP; | 579 | 0 |
| 580 | 0 | if offset < BLOCK_CAP { | 581 | 0 | // Drop the message in the slot. | 582 | 0 | let slot = (*block).slots.get_unchecked(offset); | 583 | 0 | let p = &mut *slot.msg.get(); | 584 | 0 | p.as_mut_ptr().drop_in_place(); | 585 | 0 | } else { | 586 | 0 | // Deallocate the block and move to the next one. | 587 | 0 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 0 | drop(Box::from_raw(block)); | 589 | 0 | block = next; | 590 | 0 | } | 591 | | | 592 | 0 | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 3 | if !block.is_null() { | 597 | 0 | drop(Box::from_raw(block)); | 598 | 3 | } | 599 | | } | 600 | 3 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i32> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()> as core::ops::drop::Drop>::drop <crossbeam_channel::flavors::list::Channel<usize> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 5 | fn drop(&mut self) { | 567 | 5 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 5 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 5 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 5 | | 571 | 5 | // Erase the lower bits. | 572 | 5 | head &= !((1 << SHIFT) - 1); | 573 | 5 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 6 | while head != tail { | 578 | 1 | let offset = (head >> SHIFT) % LAP; | 579 | 1 | | 580 | 1 | if offset < BLOCK_CAP { | 581 | 1 | // Drop the message in the slot. | 582 | 1 | let slot = (*block).slots.get_unchecked(offset); | 583 | 1 | let p = &mut *slot.msg.get(); | 584 | 1 | p.as_mut_ptr().drop_in_place(); | 585 | 1 | } else { | 586 | 0 | // Deallocate the block and move to the next one. | 587 | 0 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 0 | drop(Box::from_raw(block)); | 589 | 0 | block = next; | 590 | 0 | } | 591 | | | 592 | 1 | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 5 | if !block.is_null() { | 597 | 5 | drop(Box::from_raw(block)); | 598 | 5 | }0 | 599 | | } | 600 | 5 | } |
<crossbeam_channel::flavors::list::Channel<()> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 8 | fn drop(&mut self) { | 567 | 8 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 8 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 8 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 8 | | 571 | 8 | // Erase the lower bits. | 572 | 8 | head &= !((1 << SHIFT) - 1); | 573 | 8 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 10.3k | while head != tail { | 578 | 10.3k | let offset = (head >> SHIFT) % LAP; | 579 | 10.3k | | 580 | 10.3k | if offset < BLOCK_CAP { | 581 | 10.0k | // Drop the message in the slot. | 582 | 10.0k | let slot = (*block).slots.get_unchecked(offset); | 583 | 10.0k | let p = &mut *slot.msg.get(); | 584 | 10.0k | p.as_mut_ptr().drop_in_place(); | 585 | 10.0k | } else { | 586 | 323 | // Deallocate the block and move to the next one. | 587 | 323 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 323 | drop(Box::from_raw(block)); | 589 | 323 | block = next; | 590 | 323 | } | 591 | | | 592 | 10.3k | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 8 | if !block.is_null() { | 597 | 6 | drop(Box::from_raw(block)); | 598 | 6 | }2 | 599 | | } | 600 | 8 | } |
<crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 1.00k | fn drop(&mut self) { | 567 | 1.00k | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 1.00k | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 1.00k | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 1.00k | | 571 | 1.00k | // Erase the lower bits. | 572 | 1.00k | head &= !((1 << SHIFT) - 1); | 573 | 1.00k | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 1.00k | while head != tail { | 578 | 0 | let offset = (head >> SHIFT) % LAP; | 579 | 0 |
| 580 | 0 | if offset < BLOCK_CAP { | 581 | 0 | // Drop the message in the slot. | 582 | 0 | let slot = (*block).slots.get_unchecked(offset); | 583 | 0 | let p = &mut *slot.msg.get(); | 584 | 0 | p.as_mut_ptr().drop_in_place(); | 585 | 0 | } else { | 586 | 0 | // Deallocate the block and move to the next one. | 587 | 0 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 0 | drop(Box::from_raw(block)); | 589 | 0 | block = next; | 590 | 0 | } | 591 | | | 592 | 0 | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 1.00k | if !block.is_null() { | 597 | 1.00k | drop(Box::from_raw(block)); | 598 | 1.00k | }1 | 599 | | } | 600 | 1.00k | } |
<crossbeam_channel::flavors::list::Channel<i32> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 10.0k | fn drop(&mut self) { | 567 | 10.0k | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 10.0k | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 10.0k | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 10.0k | | 571 | 10.0k | // Erase the lower bits. | 572 | 10.0k | head &= !((1 << SHIFT) - 1); | 573 | 10.0k | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 13.1k | while head != tail { | 578 | 3.09k | let offset = (head >> SHIFT) % LAP; | 579 | 3.09k | | 580 | 3.09k | if offset < BLOCK_CAP { | 581 | 3.00k | // Drop the message in the slot. | 582 | 3.00k | let slot = (*block).slots.get_unchecked(offset); | 583 | 3.00k | let p = &mut *slot.msg.get(); | 584 | 3.00k | p.as_mut_ptr().drop_in_place(); | 585 | 3.00k | } else { | 586 | 96 | // Deallocate the block and move to the next one. | 587 | 96 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 96 | drop(Box::from_raw(block)); | 589 | 96 | block = next; | 590 | 96 | } | 591 | | | 592 | 3.09k | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 10.0k | if !block.is_null() { | 597 | 10.0k | drop(Box::from_raw(block)); | 598 | 10.0k | }0 | 599 | | } | 600 | 10.0k | } |
<crossbeam_channel::flavors::list::Channel<list::drops::DropCounter> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 100 | fn drop(&mut self) { | 567 | 100 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 100 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 100 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 100 | | 571 | 100 | // Erase the lower bits. | 572 | 100 | head &= !((1 << SHIFT) - 1); | 573 | 100 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 53.5k | while head != tail { | 578 | 53.4k | let offset = (head >> SHIFT) % LAP; | 579 | 53.4k | | 580 | 53.4k | if offset < BLOCK_CAP { | 581 | 51.7k | // Drop the message in the slot. | 582 | 51.7k | let slot = (*block).slots.get_unchecked(offset); | 583 | 51.7k | let p = &mut *slot.msg.get(); | 584 | 51.7k | p.as_mut_ptr().drop_in_place(); | 585 | 51.7k | } else { | 586 | 1.66k | // Deallocate the block and move to the next one. | 587 | 1.66k | let next = (*block).next.load(Ordering::Relaxed); | 588 | 1.66k | drop(Box::from_raw(block)); | 589 | 1.66k | block = next; | 590 | 1.66k | } | 591 | | | 592 | 53.4k | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 100 | if !block.is_null() { | 597 | 100 | drop(Box::from_raw(block)); | 598 | 100 | }0 | 599 | | } | 600 | 100 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<usize> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u32> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any>> as core::ops::drop::Drop>::drop <crossbeam_channel::flavors::list::Channel<i32> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 2 | fn drop(&mut self) { | 567 | 2 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 2 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 2 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 2 | | 571 | 2 | // Erase the lower bits. | 572 | 2 | head &= !((1 << SHIFT) - 1); | 573 | 2 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 2 | while head != tail { | 578 | 0 | let offset = (head >> SHIFT) % LAP; | 579 | 0 |
| 580 | 0 | if offset < BLOCK_CAP { | 581 | 0 | // Drop the message in the slot. | 582 | 0 | let slot = (*block).slots.get_unchecked(offset); | 583 | 0 | let p = &mut *slot.msg.get(); | 584 | 0 | p.as_mut_ptr().drop_in_place(); | 585 | 0 | } else { | 586 | 0 | // Deallocate the block and move to the next one. | 587 | 0 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 0 | drop(Box::from_raw(block)); | 589 | 0 | block = next; | 590 | 0 | } | 591 | | | 592 | 0 | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 2 | if !block.is_null() { | 597 | 1 | drop(Box::from_raw(block)); | 598 | 1 | } | 599 | | } | 600 | 2 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<[u8; 0]> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<golang::zerosize::zero_size_struct::ZeroSize> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::string::String> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<bool> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<()> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<u8> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<i64> as core::ops::drop::Drop>::drop <crossbeam_channel::flavors::list::Channel<usize> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 3 | fn drop(&mut self) { | 567 | 3 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 3 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 3 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 3 | | 571 | 3 | // Erase the lower bits. | 572 | 3 | head &= !((1 << SHIFT) - 1); | 573 | 3 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 3 | while head != tail { | 578 | 0 | let offset = (head >> SHIFT) % LAP; | 579 | 0 |
| 580 | 0 | if offset < BLOCK_CAP { | 581 | 0 | // Drop the message in the slot. | 582 | 0 | let slot = (*block).slots.get_unchecked(offset); | 583 | 0 | let p = &mut *slot.msg.get(); | 584 | 0 | p.as_mut_ptr().drop_in_place(); | 585 | 0 | } else { | 586 | 0 | // Deallocate the block and move to the next one. | 587 | 0 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 0 | drop(Box::from_raw(block)); | 589 | 0 | block = next; | 590 | 0 | } | 591 | | | 592 | 0 | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 3 | if !block.is_null() { | 597 | 3 | drop(Box::from_raw(block)); | 598 | 3 | }0 | 599 | | } | 600 | 3 | } |
<crossbeam_channel::flavors::list::Channel<()> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 13 | fn drop(&mut self) { | 567 | 13 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 13 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 13 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 13 | | 571 | 13 | // Erase the lower bits. | 572 | 13 | head &= !((1 << SHIFT) - 1); | 573 | 13 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 18.1k | while head != tail { | 578 | 18.1k | let offset = (head >> SHIFT) % LAP; | 579 | 18.1k | | 580 | 18.1k | if offset < BLOCK_CAP { | 581 | 17.5k | // Drop the message in the slot. | 582 | 17.5k | let slot = (*block).slots.get_unchecked(offset); | 583 | 17.5k | let p = &mut *slot.msg.get(); | 584 | 17.5k | p.as_mut_ptr().drop_in_place(); | 585 | 17.5k | } else { | 586 | 565 | // Deallocate the block and move to the next one. | 587 | 565 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 565 | drop(Box::from_raw(block)); | 589 | 565 | block = next; | 590 | 565 | } | 591 | | | 592 | 18.1k | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 13 | if !block.is_null() { | 597 | 11 | drop(Box::from_raw(block)); | 598 | 11 | }2 | 599 | | } | 600 | 13 | } |
<crossbeam_channel::flavors::list::Channel<i32> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 33 | fn drop(&mut self) { | 567 | 33 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 33 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 33 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 33 | | 571 | 33 | // Erase the lower bits. | 572 | 33 | head &= !((1 << SHIFT) - 1); | 573 | 33 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 39 | while head != tail { | 578 | 6 | let offset = (head >> SHIFT) % LAP; | 579 | 6 | | 580 | 6 | if offset < BLOCK_CAP { | 581 | 6 | // Drop the message in the slot. | 582 | 6 | let slot = (*block).slots.get_unchecked(offset); | 583 | 6 | let p = &mut *slot.msg.get(); | 584 | 6 | p.as_mut_ptr().drop_in_place(); | 585 | 6 | } else { | 586 | 0 | // Deallocate the block and move to the next one. | 587 | 0 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 0 | drop(Box::from_raw(block)); | 589 | 0 | block = next; | 590 | 0 | } | 591 | | | 592 | 6 | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 33 | if !block.is_null() { | 597 | 17 | drop(Box::from_raw(block)); | 598 | 17 | }16 | 599 | | } | 600 | 33 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant> as core::ops::drop::Drop>::drop Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<std::time::Instant> as core::ops::drop::Drop>::drop <crossbeam_channel::flavors::list::Channel<usize> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 3 | fn drop(&mut self) { | 567 | 3 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 3 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 3 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 3 | | 571 | 3 | // Erase the lower bits. | 572 | 3 | head &= !((1 << SHIFT) - 1); | 573 | 3 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 3 | while head != tail { | 578 | 0 | let offset = (head >> SHIFT) % LAP; | 579 | 0 |
| 580 | 0 | if offset < BLOCK_CAP { | 581 | 0 | // Drop the message in the slot. | 582 | 0 | let slot = (*block).slots.get_unchecked(offset); | 583 | 0 | let p = &mut *slot.msg.get(); | 584 | 0 | p.as_mut_ptr().drop_in_place(); | 585 | 0 | } else { | 586 | 0 | // Deallocate the block and move to the next one. | 587 | 0 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 0 | drop(Box::from_raw(block)); | 589 | 0 | block = next; | 590 | 0 | } | 591 | | | 592 | 0 | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 3 | if !block.is_null() { | 597 | 3 | drop(Box::from_raw(block)); | 598 | 3 | }0 | 599 | | } | 600 | 3 | } |
<crossbeam_channel::flavors::list::Channel<i32> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 19 | fn drop(&mut self) { | 567 | 19 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 19 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 19 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 19 | | 571 | 19 | // Erase the lower bits. | 572 | 19 | head &= !((1 << SHIFT) - 1); | 573 | 19 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 22 | while head != tail { | 578 | 3 | let offset = (head >> SHIFT) % LAP; | 579 | 3 | | 580 | 3 | if offset < BLOCK_CAP { | 581 | 3 | // Drop the message in the slot. | 582 | 3 | let slot = (*block).slots.get_unchecked(offset); | 583 | 3 | let p = &mut *slot.msg.get(); | 584 | 3 | p.as_mut_ptr().drop_in_place(); | 585 | 3 | } else { | 586 | 0 | // Deallocate the block and move to the next one. | 587 | 0 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 0 | drop(Box::from_raw(block)); | 589 | 0 | block = next; | 590 | 0 | } | 591 | | | 592 | 3 | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 19 | if !block.is_null() { | 597 | 8 | drop(Box::from_raw(block)); | 598 | 11 | } | 599 | | } | 600 | 19 | } |
<crossbeam_channel::flavors::list::Channel<()> as core::ops::drop::Drop>::drop Line | Count | Source | 566 | 9 | fn drop(&mut self) { | 567 | 9 | let mut head = self.head.index.load(Ordering::Relaxed); | 568 | 9 | let mut tail = self.tail.index.load(Ordering::Relaxed); | 569 | 9 | let mut block = self.head.block.load(Ordering::Relaxed); | 570 | 9 | | 571 | 9 | // Erase the lower bits. | 572 | 9 | head &= !((1 << SHIFT) - 1); | 573 | 9 | tail &= !((1 << SHIFT) - 1); | 574 | | | 575 | | unsafe { | 576 | | // Drop all messages between head and tail and deallocate the heap-allocated blocks. | 577 | 7.80k | while head != tail { | 578 | 7.79k | let offset = (head >> SHIFT) % LAP; | 579 | 7.79k | | 580 | 7.79k | if offset < BLOCK_CAP { | 581 | 7.54k | // Drop the message in the slot. | 582 | 7.54k | let slot = (*block).slots.get_unchecked(offset); | 583 | 7.54k | let p = &mut *slot.msg.get(); | 584 | 7.54k | p.as_mut_ptr().drop_in_place(); | 585 | 7.54k | } else { | 586 | 243 | // Deallocate the block and move to the next one. | 587 | 243 | let next = (*block).next.load(Ordering::Relaxed); | 588 | 243 | drop(Box::from_raw(block)); | 589 | 243 | block = next; | 590 | 243 | } | 591 | | | 592 | 7.79k | head = head.wrapping_add(1 << SHIFT); | 593 | | } | 594 | | | 595 | | // Deallocate the last remaining block. | 596 | 9 | if !block.is_null() { | 597 | 7 | drop(Box::from_raw(block)); | 598 | 7 | }2 | 599 | | } | 600 | 9 | } |
Unexecuted instantiation: <crossbeam_channel::flavors::list::Channel<alloc::boxed::Box<dyn core::any::Any + core::marker::Send>> as core::ops::drop::Drop>::drop |
601 | | } |
602 | | |
603 | | /// Receiver handle to a channel. |
604 | | pub(crate) struct Receiver<'a, T>(&'a Channel<T>); |
605 | | |
606 | | /// Sender handle to a channel. |
607 | | pub(crate) struct Sender<'a, T>(&'a Channel<T>); |
608 | | |
609 | | impl<T> SelectHandle for Receiver<'_, T> { |
610 | 987k | fn try_select(&self, token: &mut Token) -> bool { |
611 | 987k | self.0.start_recv(token) |
612 | 987k | } <crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::try_select Line | Count | Source | 610 | 297k | fn try_select(&self, token: &mut Token) -> bool { | 611 | 297k | self.0.start_recv(token) | 612 | 297k | } |
<crossbeam_channel::flavors::list::Receiver<usize> as crossbeam_channel::select::SelectHandle>::try_select Line | Count | Source | 610 | 15.5k | fn try_select(&self, token: &mut Token) -> bool { | 611 | 15.5k | self.0.start_recv(token) | 612 | 15.5k | } |
<crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::try_select Line | Count | Source | 610 | 8.46k | fn try_select(&self, token: &mut Token) -> bool { | 611 | 8.46k | self.0.start_recv(token) | 612 | 8.46k | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::try_select Line | Count | Source | 610 | 26.6k | fn try_select(&self, token: &mut Token) -> bool { | 611 | 26.6k | self.0.start_recv(token) | 612 | 26.6k | } |
<crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::try_select Line | Count | Source | 610 | 3 | fn try_select(&self, token: &mut Token) -> bool { | 611 | 3 | self.0.start_recv(token) | 612 | 3 | } |
<crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::try_select Line | Count | Source | 610 | 19.8k | fn try_select(&self, token: &mut Token) -> bool { | 611 | 19.8k | self.0.start_recv(token) | 612 | 19.8k | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::try_select Line | Count | Source | 610 | 300k | fn try_select(&self, token: &mut Token) -> bool { | 611 | 300k | self.0.start_recv(token) | 612 | 300k | } |
<crossbeam_channel::flavors::list::Receiver<usize> as crossbeam_channel::select::SelectHandle>::try_select Line | Count | Source | 610 | 21.4k | fn try_select(&self, token: &mut Token) -> bool { | 611 | 21.4k | self.0.start_recv(token) | 612 | 21.4k | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::try_select Line | Count | Source | 610 | 283k | fn try_select(&self, token: &mut Token) -> bool { | 611 | 283k | self.0.start_recv(token) | 612 | 283k | } |
<crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::try_select Line | Count | Source | 610 | 14.4k | fn try_select(&self, token: &mut Token) -> bool { | 611 | 14.4k | self.0.start_recv(token) | 612 | 14.4k | } |
|
613 | | |
614 | 0 | fn deadline(&self) -> Option<Instant> { |
615 | 0 | None |
616 | 0 | } |
617 | | |
618 | 18.5k | fn register(&self, oper: Operation, cx: &Context) -> bool { |
619 | 18.5k | self.0.receivers.register(oper, cx); |
620 | 18.5k | self.is_ready() |
621 | 18.5k | } <crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::register Line | Count | Source | 618 | 109 | fn register(&self, oper: Operation, cx: &Context) -> bool { | 619 | 109 | self.0.receivers.register(oper, cx); | 620 | 109 | self.is_ready() | 621 | 109 | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::register Line | Count | Source | 618 | 12 | fn register(&self, oper: Operation, cx: &Context) -> bool { | 619 | 12 | self.0.receivers.register(oper, cx); | 620 | 12 | self.is_ready() | 621 | 12 | } |
<crossbeam_channel::flavors::list::Receiver<usize> as crossbeam_channel::select::SelectHandle>::register Line | Count | Source | 618 | 517 | fn register(&self, oper: Operation, cx: &Context) -> bool { | 619 | 517 | self.0.receivers.register(oper, cx); | 620 | 517 | self.is_ready() | 621 | 517 | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::register Line | Count | Source | 618 | 11.9k | fn register(&self, oper: Operation, cx: &Context) -> bool { | 619 | 11.9k | self.0.receivers.register(oper, cx); | 620 | 11.9k | self.is_ready() | 621 | 11.9k | } |
<crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::register Line | Count | Source | 618 | 2 | fn register(&self, oper: Operation, cx: &Context) -> bool { | 619 | 2 | self.0.receivers.register(oper, cx); | 620 | 2 | self.is_ready() | 621 | 2 | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::register Line | Count | Source | 618 | 4 | fn register(&self, oper: Operation, cx: &Context) -> bool { | 619 | 4 | self.0.receivers.register(oper, cx); | 620 | 4 | self.is_ready() | 621 | 4 | } |
<crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::register Line | Count | Source | 618 | 328 | fn register(&self, oper: Operation, cx: &Context) -> bool { | 619 | 328 | self.0.receivers.register(oper, cx); | 620 | 328 | self.is_ready() | 621 | 328 | } |
<crossbeam_channel::flavors::list::Receiver<usize> as crossbeam_channel::select::SelectHandle>::register Line | Count | Source | 618 | 5.64k | fn register(&self, oper: Operation, cx: &Context) -> bool { | 619 | 5.64k | self.0.receivers.register(oper, cx); | 620 | 5.64k | self.is_ready() | 621 | 5.64k | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::register Line | Count | Source | 618 | 10 | fn register(&self, oper: Operation, cx: &Context) -> bool { | 619 | 10 | self.0.receivers.register(oper, cx); | 620 | 10 | self.is_ready() | 621 | 10 | } |
|
622 | | |
623 | 18.5k | fn unregister(&self, oper: Operation) { |
624 | 18.5k | self.0.receivers.unregister(oper); |
625 | 18.5k | } <crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::unregister Line | Count | Source | 623 | 109 | fn unregister(&self, oper: Operation) { | 624 | 109 | self.0.receivers.unregister(oper); | 625 | 109 | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::unregister Line | Count | Source | 623 | 12 | fn unregister(&self, oper: Operation) { | 624 | 12 | self.0.receivers.unregister(oper); | 625 | 12 | } |
<crossbeam_channel::flavors::list::Receiver<usize> as crossbeam_channel::select::SelectHandle>::unregister Line | Count | Source | 623 | 517 | fn unregister(&self, oper: Operation) { | 624 | 517 | self.0.receivers.unregister(oper); | 625 | 517 | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::unregister Line | Count | Source | 623 | 11.9k | fn unregister(&self, oper: Operation) { | 624 | 11.9k | self.0.receivers.unregister(oper); | 625 | 11.9k | } |
<crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::unregister Line | Count | Source | 623 | 2 | fn unregister(&self, oper: Operation) { | 624 | 2 | self.0.receivers.unregister(oper); | 625 | 2 | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::unregister Line | Count | Source | 623 | 4 | fn unregister(&self, oper: Operation) { | 624 | 4 | self.0.receivers.unregister(oper); | 625 | 4 | } |
<crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::unregister Line | Count | Source | 623 | 328 | fn unregister(&self, oper: Operation) { | 624 | 328 | self.0.receivers.unregister(oper); | 625 | 328 | } |
<crossbeam_channel::flavors::list::Receiver<usize> as crossbeam_channel::select::SelectHandle>::unregister Line | Count | Source | 623 | 5.64k | fn unregister(&self, oper: Operation) { | 624 | 5.64k | self.0.receivers.unregister(oper); | 625 | 5.64k | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::unregister Line | Count | Source | 623 | 10 | fn unregister(&self, oper: Operation) { | 624 | 10 | self.0.receivers.unregister(oper); | 625 | 10 | } |
|
626 | | |
627 | 2.26k | fn accept(&self, token: &mut Token, _cx: &Context) -> bool { |
628 | 2.26k | self.try_select(token) |
629 | 2.26k | } <crossbeam_channel::flavors::list::Receiver<usize> as crossbeam_channel::select::SelectHandle>::accept Line | Count | Source | 627 | 63 | fn accept(&self, token: &mut Token, _cx: &Context) -> bool { | 628 | 63 | self.try_select(token) | 629 | 63 | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::accept Line | Count | Source | 627 | 2 | fn accept(&self, token: &mut Token, _cx: &Context) -> bool { | 628 | 2 | self.try_select(token) | 629 | 2 | } |
<crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::accept Line | Count | Source | 627 | 9 | fn accept(&self, token: &mut Token, _cx: &Context) -> bool { | 628 | 9 | self.try_select(token) | 629 | 9 | } |
<crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::accept Line | Count | Source | 627 | 1 | fn accept(&self, token: &mut Token, _cx: &Context) -> bool { | 628 | 1 | self.try_select(token) | 629 | 1 | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::accept Line | Count | Source | 627 | 1.79k | fn accept(&self, token: &mut Token, _cx: &Context) -> bool { | 628 | 1.79k | self.try_select(token) | 629 | 1.79k | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::accept Line | Count | Source | 627 | 2 | fn accept(&self, token: &mut Token, _cx: &Context) -> bool { | 628 | 2 | self.try_select(token) | 629 | 2 | } |
<crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::accept Line | Count | Source | 627 | 2 | fn accept(&self, token: &mut Token, _cx: &Context) -> bool { | 628 | 2 | self.try_select(token) | 629 | 2 | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::accept Line | Count | Source | 627 | 2 | fn accept(&self, token: &mut Token, _cx: &Context) -> bool { | 628 | 2 | self.try_select(token) | 629 | 2 | } |
<crossbeam_channel::flavors::list::Receiver<usize> as crossbeam_channel::select::SelectHandle>::accept Line | Count | Source | 627 | 386 | fn accept(&self, token: &mut Token, _cx: &Context) -> bool { | 628 | 386 | self.try_select(token) | 629 | 386 | } |
|
630 | | |
631 | 102k | fn is_ready(&self) -> bool { |
632 | 102k | !self.0.is_empty() || self.0.is_disconnected()38.1k |
633 | 102k | } <crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::is_ready Line | Count | Source | 631 | 109 | fn is_ready(&self) -> bool { | 632 | 109 | !self.0.is_empty() || self.0.is_disconnected()38 | 633 | 109 | } |
<crossbeam_channel::flavors::list::Receiver<usize> as crossbeam_channel::select::SelectHandle>::is_ready Line | Count | Source | 631 | 517 | fn is_ready(&self) -> bool { | 632 | 517 | !self.0.is_empty() || self.0.is_disconnected()266 | 633 | 517 | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::is_ready Line | Count | Source | 631 | 11 | fn is_ready(&self) -> bool { | 632 | 11 | !self.0.is_empty() || self.0.is_disconnected()10 | 633 | 12 | } |
<crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::is_ready Line | Count | Source | 631 | 2 | fn is_ready(&self) -> bool { | 632 | 2 | !self.0.is_empty() || self.0.is_disconnected() | 633 | 2 | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::is_ready Line | Count | Source | 631 | 11.9k | fn is_ready(&self) -> bool { | 632 | 11.9k | !self.0.is_empty() || self.0.is_disconnected()6.29k | 633 | 11.9k | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::is_ready Line | Count | Source | 631 | 4 | fn is_ready(&self) -> bool { | 632 | 4 | !self.0.is_empty() || self.0.is_disconnected() | 633 | 4 | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::is_ready Line | Count | Source | 631 | 9 | fn is_ready(&self) -> bool { | 632 | 9 | !self.0.is_empty() || self.0.is_disconnected() | 633 | 9 | } |
<crossbeam_channel::flavors::list::Receiver<usize> as crossbeam_channel::select::SelectHandle>::is_ready Line | Count | Source | 631 | 5.64k | fn is_ready(&self) -> bool { | 632 | 5.64k | !self.0.is_empty() || self.0.is_disconnected()2.12k | 633 | 5.64k | } |
<crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::is_ready Line | Count | Source | 631 | 328 | fn is_ready(&self) -> bool { | 632 | 328 | !self.0.is_empty() || self.0.is_disconnected()141 | 633 | 328 | } |
<crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::is_ready Line | Count | Source | 631 | 67.3k | fn is_ready(&self) -> bool { | 632 | 67.3k | !self.0.is_empty() || self.0.is_disconnected()23.2k | 633 | 67.3k | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::is_ready Line | Count | Source | 631 | 156 | fn is_ready(&self) -> bool { | 632 | 156 | !self.0.is_empty() || self.0.is_disconnected()147 | 633 | 157 | } |
<crossbeam_channel::flavors::list::Receiver<usize> as crossbeam_channel::select::SelectHandle>::is_ready Line | Count | Source | 631 | 15.8k | fn is_ready(&self) -> bool { | 632 | 15.8k | !self.0.is_empty() || self.0.is_disconnected()5.89k | 633 | 15.8k | } |
|
634 | | |
635 | 11 | fn watch(&self, oper: Operation, cx: &Context) -> bool { |
636 | 11 | self.0.receivers.watch(oper, cx); |
637 | 11 | self.is_ready() |
638 | 11 | } <crossbeam_channel::flavors::list::Receiver<usize> as crossbeam_channel::select::SelectHandle>::watch Line | Count | Source | 635 | 1 | fn watch(&self, oper: Operation, cx: &Context) -> bool { | 636 | 1 | self.0.receivers.watch(oper, cx); | 637 | 1 | self.is_ready() | 638 | 1 | } |
<crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::watch Line | Count | Source | 635 | 5 | fn watch(&self, oper: Operation, cx: &Context) -> bool { | 636 | 5 | self.0.receivers.watch(oper, cx); | 637 | 5 | self.is_ready() | 638 | 5 | } |
<crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::watch Line | Count | Source | 635 | 5 | fn watch(&self, oper: Operation, cx: &Context) -> bool { | 636 | 5 | self.0.receivers.watch(oper, cx); | 637 | 5 | self.is_ready() | 638 | 5 | } |
|
639 | | |
640 | 11 | fn unwatch(&self, oper: Operation) { |
641 | 11 | self.0.receivers.unwatch(oper); |
642 | 11 | } <crossbeam_channel::flavors::list::Receiver<i32> as crossbeam_channel::select::SelectHandle>::unwatch Line | Count | Source | 640 | 5 | fn unwatch(&self, oper: Operation) { | 641 | 5 | self.0.receivers.unwatch(oper); | 642 | 5 | } |
<crossbeam_channel::flavors::list::Receiver<usize> as crossbeam_channel::select::SelectHandle>::unwatch Line | Count | Source | 640 | 1 | fn unwatch(&self, oper: Operation) { | 641 | 1 | self.0.receivers.unwatch(oper); | 642 | 1 | } |
<crossbeam_channel::flavors::list::Receiver<()> as crossbeam_channel::select::SelectHandle>::unwatch Line | Count | Source | 640 | 5 | fn unwatch(&self, oper: Operation) { | 641 | 5 | self.0.receivers.unwatch(oper); | 642 | 5 | } |
|
643 | | } |
644 | | |
645 | | impl<T> SelectHandle for Sender<'_, T> { |
646 | 55.8k | fn try_select(&self, token: &mut Token) -> bool { |
647 | 55.8k | self.0.start_send(token) |
648 | 55.8k | } <crossbeam_channel::flavors::list::Sender<i32> as crossbeam_channel::select::SelectHandle>::try_select Line | Count | Source | 646 | 9 | fn try_select(&self, token: &mut Token) -> bool { | 647 | 9 | self.0.start_send(token) | 648 | 9 | } |
<crossbeam_channel::flavors::list::Sender<()> as crossbeam_channel::select::SelectHandle>::try_select Line | Count | Source | 646 | 4.40k | fn try_select(&self, token: &mut Token) -> bool { | 647 | 4.40k | self.0.start_send(token) | 648 | 4.40k | } |
<crossbeam_channel::flavors::list::Sender<()> as crossbeam_channel::select::SelectHandle>::try_select Line | Count | Source | 646 | 1 | fn try_select(&self, token: &mut Token) -> bool { | 647 | 1 | self.0.start_send(token) | 648 | 1 | } |
<crossbeam_channel::flavors::list::Sender<i32> as crossbeam_channel::select::SelectHandle>::try_select Line | Count | Source | 646 | 18 | fn try_select(&self, token: &mut Token) -> bool { | 647 | 18 | self.0.start_send(token) | 648 | 18 | } |
<crossbeam_channel::flavors::list::Sender<()> as crossbeam_channel::select::SelectHandle>::try_select Line | Count | Source | 646 | 9.73k | fn try_select(&self, token: &mut Token) -> bool { | 647 | 9.73k | self.0.start_send(token) | 648 | 9.73k | } |
<crossbeam_channel::flavors::list::Sender<()> as crossbeam_channel::select::SelectHandle>::try_select Line | Count | Source | 646 | 41.7k | fn try_select(&self, token: &mut Token) -> bool { | 647 | 41.7k | self.0.start_send(token) | 648 | 41.7k | } |
|
649 | | |
650 | 0 | fn deadline(&self) -> Option<Instant> { |
651 | 0 | None |
652 | 0 | } |
653 | | |
654 | 0 | fn register(&self, _oper: Operation, _cx: &Context) -> bool { |
655 | 0 | self.is_ready() |
656 | 0 | } |
657 | | |
658 | 0 | fn unregister(&self, _oper: Operation) {} |
659 | | |
660 | 0 | fn accept(&self, token: &mut Token, _cx: &Context) -> bool { |
661 | 0 | self.try_select(token) |
662 | 0 | } |
663 | | |
664 | 9 | fn is_ready(&self) -> bool { |
665 | 9 | true |
666 | 9 | } |
667 | | |
668 | 0 | fn watch(&self, _oper: Operation, _cx: &Context) -> bool { |
669 | 0 | self.is_ready() |
670 | 0 | } |
671 | | |
672 | 0 | fn unwatch(&self, _oper: Operation) {} Unexecuted instantiation: <crossbeam_channel::flavors::list::ListToken as core::fmt::Debug>::fmt |
673 | | } |