crossbeam-epoch/src/default.rs
Line | Count | Source |
1 | | //! The default garbage collector. |
2 | | //! |
3 | | //! For each thread, a participant is lazily initialized on its first use, when the current thread |
4 | | //! is registered in the default collector. If initialized, the thread's participant will get |
5 | | //! destructed on thread exit, which in turn unregisters the thread. |
6 | | |
7 | | use crate::collector::{Collector, LocalHandle}; |
8 | | use crate::primitive::{lazy_static, thread_local}; |
9 | | use crate::guard::Guard; |
10 | | |
11 | | lazy_static! { |
12 | | /// The global data for the default garbage collector. |
13 | | static ref COLLECTOR: Collector = Collector::new(); |
14 | | } |
15 | | |
16 | | thread_local! { |
17 | | /// The per-thread participant for the default garbage collector. |
18 | | static HANDLE: LocalHandle = COLLECTOR.register(); |
19 | | } |
20 | | |
21 | | /// Pins the current thread. |
22 | | #[inline] |
23 | 9.89M | pub fn pin() -> Guard { |
24 | 10.2M | with_handle(|handle| handle.pin()) crossbeam_epoch::default::pin::{closure#0} Line | Count | Source | 24 | 206 | with_handle(|handle| handle.pin()) |
crossbeam_epoch::default::pin::{closure#0} Line | Count | Source | 24 | 3 | with_handle(|handle| handle.pin()) |
crossbeam_epoch::default::pin::{closure#0} Line | Count | Source | 24 | 18 | with_handle(|handle| handle.pin()) |
crossbeam_epoch::default::pin::{closure#0} Line | Count | Source | 24 | 1 | with_handle(|handle| handle.pin()) |
crossbeam_epoch::default::pin::{closure#0} Line | Count | Source | 24 | 417k | with_handle(|handle| handle.pin()) |
crossbeam_epoch::default::pin::{closure#0} Line | Count | Source | 24 | 14 | with_handle(|handle| handle.pin()) |
crossbeam_epoch::default::pin::{closure#0} Line | Count | Source | 24 | 583k | with_handle(|handle| handle.pin()) |
crossbeam_epoch::default::pin::{closure#0} Line | Count | Source | 24 | 9.27M | with_handle(|handle| handle.pin()) |
|
25 | 9.89M | } crossbeam_epoch::default::pin Line | Count | Source | 23 | 206 | pub fn pin() -> Guard { | 24 | 206 | with_handle(|handle| handle.pin()) | 25 | 206 | } |
Unexecuted instantiation: crossbeam_epoch::default::pin crossbeam_epoch::default::pin Line | Count | Source | 23 | 3 | pub fn pin() -> Guard { | 24 | 3 | with_handle(|handle| handle.pin()) | 25 | 3 | } |
crossbeam_epoch::default::pin Line | Count | Source | 23 | 18 | pub fn pin() -> Guard { | 24 | 18 | with_handle(|handle| handle.pin()) | 25 | 18 | } |
crossbeam_epoch::default::pin Line | Count | Source | 23 | 1 | pub fn pin() -> Guard { | 24 | 1 | with_handle(|handle| handle.pin()) | 25 | 1 | } |
crossbeam_epoch::default::pin Line | Count | Source | 23 | 431k | pub fn pin() -> Guard { | 24 | 431k | with_handle(|handle| handle.pin()) | 25 | 431k | } |
crossbeam_epoch::default::pin Line | Count | Source | 23 | 14 | pub fn pin() -> Guard { | 24 | 14 | with_handle(|handle| handle.pin()) | 25 | 14 | } |
crossbeam_epoch::default::pin Line | Count | Source | 23 | 533k | pub fn pin() -> Guard { | 24 | 533k | with_handle(|handle| handle.pin()) | 25 | 533k | } |
crossbeam_epoch::default::pin Line | Count | Source | 23 | 8.92M | pub fn pin() -> Guard { | 24 | 8.92M | with_handle(|handle| handle.pin()) | 25 | 8.92M | } |
|
26 | | |
27 | | /// Returns `true` if the current thread is pinned. |
28 | | #[inline] |
29 | 981k | pub fn is_pinned() -> bool { |
30 | 1.04M | with_handle(|handle| handle.is_pinned()) crossbeam_epoch::default::is_pinned::{closure#0} Line | Count | Source | 30 | 455k | with_handle(|handle| handle.is_pinned()) |
crossbeam_epoch::default::is_pinned::{closure#0} Line | Count | Source | 30 | 14 | with_handle(|handle| handle.is_pinned()) |
crossbeam_epoch::default::is_pinned::{closure#0} Line | Count | Source | 30 | 594k | with_handle(|handle| handle.is_pinned()) |
|
31 | 981k | } crossbeam_epoch::default::is_pinned Line | Count | Source | 29 | 424k | pub fn is_pinned() -> bool { | 30 | 424k | with_handle(|handle| handle.is_pinned()) | 31 | 424k | } |
crossbeam_epoch::default::is_pinned Line | Count | Source | 29 | 14 | pub fn is_pinned() -> bool { | 30 | 14 | with_handle(|handle| handle.is_pinned()) | 31 | 14 | } |
crossbeam_epoch::default::is_pinned Line | Count | Source | 29 | 556k | pub fn is_pinned() -> bool { | 30 | 556k | with_handle(|handle| handle.is_pinned()) | 31 | 556k | } |
|
32 | | |
33 | | /// Returns the default global collector. |
34 | 24 | pub fn default_collector() -> &'static Collector { |
35 | 24 | &COLLECTOR |
36 | 24 | } |
37 | | |
38 | | #[inline] |
39 | 10.7M | fn with_handle<F, R>(mut f: F) -> R |
40 | 10.7M | where |
41 | 10.7M | F: FnMut(&LocalHandle) -> R, |
42 | 10.7M | { |
43 | 10.7M | HANDLE |
44 | 11.1M | .try_with(|h| f(h)) crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard>::{closure#0} Line | Count | Source | 44 | 206 | .try_with(|h| f(h)) |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard>::{closure#0} Line | Count | Source | 44 | 3 | .try_with(|h| f(h)) |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard>::{closure#0} Line | Count | Source | 44 | 18 | .try_with(|h| f(h)) |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard>::{closure#0} Line | Count | Source | 44 | 1 | .try_with(|h| f(h)) |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard>::{closure#0} Line | Count | Source | 44 | 431k | .try_with(|h| f(h)) |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::is_pinned::{closure#0}, bool>::{closure#0} Line | Count | Source | 44 | 415k | .try_with(|h| f(h)) |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard>::{closure#0} Line | Count | Source | 44 | 14 | .try_with(|h| f(h)) |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::is_pinned::{closure#0}, bool>::{closure#0} Line | Count | Source | 44 | 14 | .try_with(|h| f(h)) |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard>::{closure#0} Line | Count | Source | 44 | 589k | .try_with(|h| f(h)) |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::is_pinned::{closure#0}, bool>::{closure#0} Line | Count | Source | 44 | 586k | .try_with(|h| f(h)) |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard>::{closure#0} Line | Count | Source | 44 | 9.11M | .try_with(|h| f(h)) |
|
45 | 10.7M | .unwrap_or_else(|_| f(&COLLECTOR.register())) |
46 | 10.7M | } crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard> Line | Count | Source | 39 | 206 | fn with_handle<F, R>(mut f: F) -> R | 40 | 206 | where | 41 | 206 | F: FnMut(&LocalHandle) -> R, | 42 | 206 | { | 43 | 206 | HANDLE | 44 | 206 | .try_with(|h| f(h)) | 45 | 206 | .unwrap_or_else(|_| f(&COLLECTOR.register())) | 46 | 206 | } |
Unexecuted instantiation: crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard> crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard> Line | Count | Source | 39 | 3 | fn with_handle<F, R>(mut f: F) -> R | 40 | 3 | where | 41 | 3 | F: FnMut(&LocalHandle) -> R, | 42 | 3 | { | 43 | 3 | HANDLE | 44 | 3 | .try_with(|h| f(h)) | 45 | 3 | .unwrap_or_else(|_| f(&COLLECTOR.register())) | 46 | 3 | } |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard> Line | Count | Source | 39 | 18 | fn with_handle<F, R>(mut f: F) -> R | 40 | 18 | where | 41 | 18 | F: FnMut(&LocalHandle) -> R, | 42 | 18 | { | 43 | 18 | HANDLE | 44 | 18 | .try_with(|h| f(h)) | 45 | 18 | .unwrap_or_else(|_| f(&COLLECTOR.register())) | 46 | 18 | } |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard> Line | Count | Source | 39 | 1 | fn with_handle<F, R>(mut f: F) -> R | 40 | 1 | where | 41 | 1 | F: FnMut(&LocalHandle) -> R, | 42 | 1 | { | 43 | 1 | HANDLE | 44 | 1 | .try_with(|h| f(h)) | 45 | 1 | .unwrap_or_else(|_| f(&COLLECTOR.register())) | 46 | 1 | } |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard> Line | Count | Source | 39 | 392k | fn with_handle<F, R>(mut f: F) -> R | 40 | 392k | where | 41 | 392k | F: FnMut(&LocalHandle) -> R, | 42 | 392k | { | 43 | 392k | HANDLE | 44 | 392k | .try_with(|h| f(h)) | 45 | 392k | .unwrap_or_else(|_| f(&COLLECTOR.register())) | 46 | 392k | } |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::is_pinned::{closure#0}, bool> Line | Count | Source | 39 | 416k | fn with_handle<F, R>(mut f: F) -> R | 40 | 416k | where | 41 | 416k | F: FnMut(&LocalHandle) -> R, | 42 | 416k | { | 43 | 416k | HANDLE | 44 | 416k | .try_with(|h| f(h)) | 45 | 416k | .unwrap_or_else(|_| f(&COLLECTOR.register())) | 46 | 416k | } |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard> Line | Count | Source | 39 | 14 | fn with_handle<F, R>(mut f: F) -> R | 40 | 14 | where | 41 | 14 | F: FnMut(&LocalHandle) -> R, | 42 | 14 | { | 43 | 14 | HANDLE | 44 | 14 | .try_with(|h| f(h)) | 45 | 14 | .unwrap_or_else(|_| f(&COLLECTOR.register())) | 46 | 14 | } |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::is_pinned::{closure#0}, bool> Line | Count | Source | 39 | 14 | fn with_handle<F, R>(mut f: F) -> R | 40 | 14 | where | 41 | 14 | F: FnMut(&LocalHandle) -> R, | 42 | 14 | { | 43 | 14 | HANDLE | 44 | 14 | .try_with(|h| f(h)) | 45 | 14 | .unwrap_or_else(|_| f(&COLLECTOR.register())) | 46 | 14 | } |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard> Line | Count | Source | 39 | 571k | fn with_handle<F, R>(mut f: F) -> R | 40 | 571k | where | 41 | 571k | F: FnMut(&LocalHandle) -> R, | 42 | 571k | { | 43 | 571k | HANDLE | 44 | 571k | .try_with(|h| f(h)) | 45 | 571k | .unwrap_or_else(|_| f(&COLLECTOR.register())) | 46 | 571k | } |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::is_pinned::{closure#0}, bool> Line | Count | Source | 39 | 542k | fn with_handle<F, R>(mut f: F) -> R | 40 | 542k | where | 41 | 542k | F: FnMut(&LocalHandle) -> R, | 42 | 542k | { | 43 | 542k | HANDLE | 44 | 542k | .try_with(|h| f(h)) | 45 | 542k | .unwrap_or_else(|_| f(&COLLECTOR.register())) | 46 | 542k | } |
crossbeam_epoch::default::with_handle::<crossbeam_epoch::default::pin::{closure#0}, crossbeam_epoch::guard::Guard> Line | Count | Source | 39 | 8.80M | fn with_handle<F, R>(mut f: F) -> R | 40 | 8.80M | where | 41 | 8.80M | F: FnMut(&LocalHandle) -> R, | 42 | 8.80M | { | 43 | 8.80M | HANDLE | 44 | 8.80M | .try_with(|h| f(h)) | 45 | 8.80M | .unwrap_or_else(|_| f(&COLLECTOR.register())) | 46 | 8.80M | } |
|
47 | | |
48 | | #[cfg(all(test, not(loom_crossbeam)))] |
49 | | mod tests { |
50 | | use crossbeam_utils::thread; |
51 | | |
52 | | #[test] |
53 | 1 | fn pin_while_exiting() { crossbeam_epoch::default::tests::pin_while_exiting::{closure#0} Line | Count | Source | 53 | 1 | fn pin_while_exiting() { |
|
54 | 1 | struct Foo; |
55 | 1 | |
56 | 1 | impl Drop for Foo { |
57 | 1 | fn drop(&mut self) { |
58 | 1 | // Pin after `HANDLE` has been dropped. This must not panic. |
59 | 1 | super::pin(); |
60 | 1 | } |
61 | 1 | } |
62 | 1 | |
63 | 1 | thread_local! { |
64 | 1 | static FOO: Foo = Foo; |
65 | 1 | } |
66 | 1 | |
67 | 1 | thread::scope(|scope| { |
68 | 1 | scope.spawn(|_| { |
69 | 1 | // Initialize `FOO` and then `HANDLE`. |
70 | 1 | FOO.with(|_| ()); |
71 | 1 | super::pin(); |
72 | 1 | // At thread exit, `HANDLE` gets dropped first and `FOO` second. |
73 | 1 | }); |
74 | 1 | }) |
75 | 1 | .unwrap(); |
76 | 1 | } crossbeam_epoch::default::tests::pin_while_exiting Line | Count | Source | 53 | 1 | fn pin_while_exiting() { | 54 | 1 | struct Foo; | 55 | 1 | | 56 | 1 | impl Drop for Foo { | 57 | 1 | fn drop(&mut self) { | 58 | 1 | // Pin after `HANDLE` has been dropped. This must not panic. | 59 | 1 | super::pin(); | 60 | 1 | } | 61 | 1 | } | 62 | 1 | | 63 | 1 | thread_local! { | 64 | 1 | static FOO: Foo = Foo; | 65 | 1 | } | 66 | 1 | | 67 | 1 | thread::scope(|scope| { | 68 | | scope.spawn(|_| { | 69 | | // Initialize `FOO` and then `HANDLE`. | 70 | | FOO.with(|_| ()); | 71 | | super::pin(); | 72 | | // At thread exit, `HANDLE` gets dropped first and `FOO` second. | 73 | | }); | 74 | 1 | }) | 75 | 1 | .unwrap(); | 76 | 1 | } |
|
77 | | } |