     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94

    // Definition of global epoch state. The `get` function is the way to
    // access this data externally (until const fn is stabilized...).

    use std::sync::atomic::AtomicUsize;

    use mem::CachePadded;
    use mem::epoch::garbage;
    use mem::epoch::participants::Participants;

    /// Global epoch state
    pub struct EpochState {
        /// Current global epoch
        pub epoch: CachePadded<AtomicUsize>,

        // FIXME: move this into the `garbage` module, rationalize API
        /// Global garbage bags
        pub garbage: [CachePadded<garbage::ConcBag>; 3],

        /// Participant list
        pub participants: Participants,
    }

    unsafe impl Send for EpochState {}
    unsafe impl Sync for EpochState {}

    pub use self::imp::get;

    #[cfg(not(feature = "nightly"))]
    mod imp {
        use std::mem;
        use std::sync::atomic::{self, AtomicUsize};
        use std::sync::atomic::Ordering::Relaxed;

        use super::EpochState;
        use mem::CachePadded;
        use mem::epoch::participants::Participants;

        impl EpochState {
            fn new() -> EpochState {
                EpochState {
                    epoch: CachePadded::zeroed(),
                    garbage: [CachePadded::zeroed(),
                              CachePadded::zeroed(),
                              CachePadded::zeroed()],
                    participants: Participants::new(),
                }
            }
        }

        static EPOCH: AtomicUsize = atomic::ATOMIC_USIZE_INIT;

        pub fn get() -> &'static EpochState {
            let mut addr = EPOCH.load(Relaxed);

            if addr == 0 {
                let boxed = Box::new(EpochState::new());
                let raw = Box::into_raw(boxed);

                addr = EPOCH.compare_and_swap(0, raw as usize, Relaxed);
                if addr != 0 {
                    let boxed = unsafe { Box::from_raw(raw) };
                    mem::drop(boxed);
                } else {
                    addr = raw as usize;
                }
            }

            unsafe {
                &*(addr as *mut EpochState)
            }
        }
    }

    #[cfg(feature = "nightly")]
    mod imp {
        use super::EpochState;
        use mem::CachePadded;
        use mem::epoch::participants::Participants;

        impl EpochState {
            const fn new() -> EpochState {
                EpochState {
                    epoch: CachePadded::zeroed(),
                    garbage: [CachePadded::zeroed(),
                              CachePadded::zeroed(),
                              CachePadded::zeroed()],
                    participants: Participants::new(),
                }
            }
        }

        static EPOCH: EpochState = EpochState::new();
        pub fn get() -> &'static EpochState { &EPOCH }
    }

# Help

## Keyboard Shortcuts

?
  Show this help dialog
S
  Focus the search field
⇤
  Move up in search results
⇥
  Move down in search results
⏎
  Go to active search result

## Search Tricks

Prefix searches with a type followed by a colon (e.g. `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g. `vec -> usize` or `* -> vec`)