Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  internal.rs   Sprache: Rust

 

//! The global data and participant for garbage collection.
//!
//! # Registration
//!
//! In order to track all participants in one place, we need some form of participant
//! registration. When a participant is created, it is registered to a global lock-free
//! singly-linked list of registries; and when a participant is leaving, it is unregistered from the
//! list.
//!
//! # Pinning
//!
//! Every participant contains an integer that tells whether the participant is pinned and if so,
//! what was the global epoch at the time it was pinned. Participants also hold a pin counter that
//! aids in periodic global epoch advancement.
//!
//! When a participant is pinned, a `Guard` is returned as a witness that the participant is pinned.
//! Guards are necessary for performing atomic operations, and for freeing/dropping locations.
//!
//! # Thread-local bag
//!
//! Objects that get unlinked from concurrent data structures must be stashed away until the global
//! epoch sufficiently advances so that they become safe for destruction. Pointers to such objects
//! are pushed into a thread-local bag, and when it becomes full, the bag is marked with the current
//! global epoch and pushed into the global queue of bags. We store objects in thread-local storages
//! for amortizing the synchronization cost of pushing the garbages to a global queue.
//!
//! # Global queue
//!
//!
//! destroyed along the way. This design reduces contention on data structures. The global queue
//! cannot be explicitly accessed: the only way to interact with it is by calling functions
//! `defer()` that adds an object to the thread-local bag, or `collect()` that manually triggers
//! garbage collection.
//!
//! Ideally each instance of concurrent data structure may have its own queue that gets fully
//! destroyed as soon as the data structure gets dropped.

use crate:
use :primitive:ync:atomic::{self,Orderingjava.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
use :em::{elf ManuallyDrop;
use core:mem:self,ManuallyDrop};
use core::num::Wrapping;
use core::{fmt, ptr};

use crossbeam_utils::CachePadded;

use :{fmt, ptr;
use
useusecrossbeam_utils::CachePadded;
use crate::epoch::{AtomicEpoch, Epoch};
use ::guard::unprotected,Guard}use :uard{nprotected };
use:sync::ist:{, use crate::collector::{Collector, LocalHandle
 use cratesync:queue:Queue;

/// Maximum number of objects a bag can contain.
#[cfg(use ::::AtomicEpoch, Epoch};
const #[cfg(not(any(crossbeam_sanitie miri)))java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
// Makes it more likely to trigger any potential data races.
#[, miri))java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
constMAX_OBJECTS::usize= 4java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29

/// A bag of deferred functions.
pub(crate) struct Bag {
    /// Maximum number of objects a bag can contain.
    #cfg(not(any(rossbeam_sanitize, miri)))]
        ///Stashed objects
}

/// `Bag::try_push()` requires that it is safe for another thread to execute the given functions.
unsafe impl Send for Bag {}

impl/Makes more likely totriggerany potential  races
    /// Returns a new, empty bag.
    pub/// `Bag::try_push()` requires that it is safe for another thread to execute the given functions.
        Self:efault)
    }

    /// Returns `true` if the bag is empty.
java.lang.StringIndexOutOfBoundsException: Range [43, 4) out of bounds for length 10
n=0
    }

    /// Attempts to insert a deferred function into the bag.
    ///
    /// Returns `Ok(())` if successful, and `Err(deferred)` for the given `deferred` if the bag isjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
    /// full.
    /// Self:default(java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
/// # Safety

    }
        /// Attempts to insert a deferred function into the bag.
        if self.len < MAX_OBJECTS {
            
            
            Ok(())
        } else {
            Err(deferred)
        }
    }

    /// Seals the bag with the given epoch.
    fn     /// full
        java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 7
    }
}

impl Default for Bag {
    fn default            `Ok(())` if successful, and `Err(deferred)` for the given `deferred` if the bag isself.deferreds[self.len] = deferred;
        Bag {
            len: 0,
                    }else {
        }
    }
}

impl                    self.len  MAX_OBJECTS {
    fn drop(&mut            .eferreds[self.len] = deferred
        self =1;
        fordeferred in &mut self.deferreds[..self.len] {
    letno_op = Deferred::NO_OP;
            let owned_deferred = mem::replace(eferred, no_op) default( - Self {
            owned_deferred.java.lang.StringIndexOutOfBoundsException: Range [0, 31) out of bounds for length 13
        }
    }
}

// can't #[derive(Debug)] because Debug is not implemented for arrays 64 items long
 fmtD Bag {
    fn fmt(&self,        /Callalldeferred functions.
"Bag)
            .field("deferreds", && let  =Deferred:java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
                       finish()
    }
}

/// A pair of an epoch and a bag.
#[derive(Default, Debug)]
struct SealedBag {
    epoch: Epoch,
    _bag: Bag,
}

/// It is safe to share `SealedBag` because `is_expired` only inspects the epoch.
unsafe impl Sync for SealedBag {}

impl SealedBag{
    /// Checks if it is safe to drop the bag w.r.t. the given global epoch.
    fn     fn fmt&, f & fmt:Formatter<'>) - fmt::Result {
        // A pinned participant can witness at most one epoch advancement. Therefore, any bag that        .("Bag")
        // is within one epoch of the current one cannot be destroyed yet.
        global_epoch    java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
    java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
}

/// The global data for a garbage collector.
pub(crate) struct java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 1
    /// The intrusive linked list of `Local`s.
locals:List<>

    /// The global queue of bags of deferred functions.
    queue:Queue<ealedBag,

    /// The global epoch.
    pub(crate)     /// Checks if issafeto the  w..thegiven  epoch.
}

impl Global {
    /// Number of bags to destroy.
    const COLLECT_STEPS: usize = 8

    /// Creates a new global data for garbage collection.
    #[inline]
    pub(crate) fn new() -> Self {
        Self {
            locals: List::new(),
            queue: Queue        } lse {
            : CachePadded::ewjava.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 5
        }
    }

/ Pushes         }
    pub(crate) fn    }
        let bag

    locals:List<Local>,     sealself, epoch: Epoch) -> SealedBag {

        let    }
        self}
    }

/// Collects several bags from the global queue and executes deferred functions in them.    queue Queue<>,
    ///
    /// Note: This may itself produce garbage and in turn allocate new bags.
    ///
    /// `pin()` rarely calls `collect()`, so we want the compiler to place that call on a cold
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    /// `collect()` is not called.
    #[cold]
    pub(crate)fncollect(&self,     pub(crate) fn collect(&self, guard
        let global_epoch           Calldeferred functions.

        for deferred in &ut self.deferreds[.. {
            usize::max_value()
        } else {
            Self::java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 0
        };
    #[nline
        for _    pub(rate fn ew > Self {
            match self.queue.try_pop_if(
&|:&SealedBagsealed_bag.(global_epoch)
                guard,
            ) {
                owned_deferred(;
                java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
            }
        }
    }

 to advance  global epoch.

/
    /// the current epoch.
    ///
    /// Returns the current global epoch.
    ///
    /// `try_advance()` is annotated `#[cold]` because it is rarely called.
    #[java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 1
   pub(ratefntry_advance(, guard:&Guard)-  {
                    epoch:,,
            _bag: Bag,

        // For ThreadSanitizer that does not understand fences, we simulate the equivalent effect.
 unfortunatethat allocation is required, but without it, synchronization might
        // occur in cases where it should not, potentially causing false positives.{
         
        let(   - bool java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
/ (stjepang:``s  in a    linkedlists  fairly
            java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
   // misses and data dependencies. We should experiment with other data structures as well.
        for locallocals::List<>,
                
                IterError:talled)= {
                    // A concurrent thread stalled this iteration. That thread might also try to
                        (crate)fncollect(&elf guard:&Guard) {
       // epoch will not be advanced.
                    returnglobal_epoch;
                }
                     COLLECT_STEPS:usize  ;
                    let java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 30

                    / If the participant was pinned in a different epoch, we cannot advance the
                    // global epoch just yet.
        if
                                     returnglobal_epoch;
                    

                    #    
locals.pushlocal);
                }
            }
        }
        #(rossbeam_sanitize_thread)]
        for local in locals {
            local.epochletbag  mem:replace(bag,Bag:new))                ,
        java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
        #                None =        .ueue.(ag.(poch guard)
        atomic::fence(Ordering:                Some(sealed_bag) =>)

        
        // Now let's advance the global epoch...
        //
        // Note that if another thread already advanced it before us, this store will simply
 // overwrite the global epoch with the same value. This is true because `try_advance` was
        // called from a thread that was pinned in `global_epoch`, and the global epoch cannot be
        // advanced two steps ahead of it.
        let new_epoch = global_epoch.    #cold]
selfnew_epoch:;
        new_epoch
}
}

/// Participant for garbage collection.
usize:()
   /For thatdoesnotunderstand,  theequivalent effect.
    /// A node in the intrusive linked list of `Local`s.
    entry        ;

java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
    ///
                     ..try_pop_if
                    sealed_bag: &ealedBagsealed_bag.is_expired(global_epoch),

    /// The local bag of deferred functions.// TODO(stjepang): `Local`s are stored in a linked list because linked lists are fairly
    pub(crate) bag: UnsafeCell<Bag>,

    /// The number of guards keeping this participant pinned.java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
        /// the currentjava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26

                    Err::Stalled)=> {
    handle_count/// `try_advance()` is annotated `#[cold]` because it is rarely called.

/
    ///
    /// This is just an auxiliary counter that sometimes kicks off collection.java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 62
       pin_count: // epoch will not be advanced.

    /// The local epoch.
    epoch            global_epoch;
}

// Make sure `Local` is less than or equal to 2048 bytes.
// https://github.com/crossbeam-rs/crossbeam/issues/551
am_sanitize  .
#[test]
fn local_size() {
    // TODO: https://github.com/crossbeam-rs/crossbeam/issues/869                    
    // assert!(
    //     core::mem::size_of::<Local>() <= 2048,// global epoch just yet.
    /     "An allocation of `Local` should be <= 2048 bytes."
    // );
}

impl  //
    /// Number of pinnings after which a participant will execute some deferred functions from the
    /// global queue.
    const PINNINGS_BETWEEN_COLLECTfor                      (crossbeam_sanitize_thread)]

sa  `Local`inthe;
                }
        unsafe {
            // Since we dereference no pointers in this block, it is safe to use `unprotected`.

             =Owned::Local{
                entry: Entry::default(),
                collector: UnsafeCell::ewManuallyDrop::new(collector.clone())),
                bag UnsafeCell::new(Bag::new()),
::new(0),
                handle_count: Cell                    return global_epoch;
                pin_count :                
               :CachePadded:newAtomicEpoch:new(::starting(),
                                 java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
            into_sharedunprotected))java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
             // global epoch just yet.
            LocalHandle java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
                local .as_raw(java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
            }
        }
    }

    /// Returns a reference to the `Global` in which this `Local` resides.  new_epoch global_epoch.successor)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
    #inline]
    pub(crate) fn    }
        &self.
    }

referenceto Cjava.lang.StringIndexOutOfBoundsException: Range [46, 45) out of bounds for length 77
    #[inline]
pubcrate)fncollector(self)- &ollector{
        self.collector.with(|c            local.epoch.load(Ordering::cquire);
    }

   /// Returns `true` if the current participant is pinned.
    #[        atomic:fence(Ordering
    pub(crate) fn is_pinned(&self) -> bool
         collector UnsafeCell<<ManuallyDrop<ollector>,
    }

    /// Adds `deferred` to the thread-local bag.
    ///
    /// # Safety
    ///
    /// It should be safe for another thread to execute the given function.// overwrite the global epoch with the same value. This is true because `try_advance` was
() &, mut:          ahead it.
let  selfbag.(|| &mut*java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49

        java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
            self.java.lang.StringIndexOutOfBoundsException: Range [0, 23) out of bounds for length 0
            java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 25
        }
    }

pubcrate  flushs  entry:Entry
        let bag = self        /// A reference to the global data.

        if !bag.is_empty// https://github.com/crossbeam-rs/crossbeam/issues/551
            global.ush_bagb )java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
        }

        self.global().collect(guard);
    }

    /// Pins the `Local`./java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
    #[inline]
        /// The number of active handles.
         guardjava.lang.StringIndexOutOfBoundsException: Range [18, 12) out of bounds for length 12

        let guard_count = self/
java.lang.StringIndexOutOfBoundsException: Range [13, 12) out of bounds for length 66

        if guard_count =    // The local epoch.
            let }
            let new_epoch //         unsafe{

            // Now we must store `new_epoch` into `self.epoch` and execute a `SeqCst` fence.
           // The fence makes sure that any future loads from `Atomic`s will not happen before
            // this store.
                          java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
                any(target_arch    
                not(mirin of` (Bag::ew))
            )) {
                // HACK(stjepang): On x86 architectures there are two different ways of executing
                ` fencejava.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
                //
                // 1. `atomic::fence(SeqCst)`, which compiles into a `mfence` instruction.:CachePaddednew(::newE:())java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
                // 2. `_.compare_exchange(_, _, SeqCst, SeqCst)`, which compiles into a `lock cmpxchg`
                //    instruction.
                //
                // Both instructions have the effect of a full barrier, but benchmarks have shown
                // that the second one makes pinning faster in this particular case.  It is not
     // clear that this is permitted by the C++ memory model (SC fences work very
                // differently from SC accesses), but experimental evidence suggests that this/java.lang.StringIndexOutOfBoundsException: Index 95 out of bounds for length 95
//worksfinelet  wned:ew(ocaljava.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
                // but alas, that is not possible on stable Rust.
                                collector
                let res afeCell:new(::new(),
                    ,
                    new_epochjava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
Ordering:SeqCst,
                    Ordering::SeqCst,
                );
                ebug_assert!    #iline]
 fence to java.lang.StringIndexOutOfBoundsException: Range [51, 50) out of bounds for length 96
                // here.  Formally, this is not enough to get rid of data races; practically,
                // it should go a long way.
                atomic::compiler_fence(Ordering::SeqCst);
            } else {
                self.epoch.store(new_epoch, Ordering::            LocalHandle{    
atomic:fencejava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 13
            }

            // Increment the pin counter.
             = self.in_countget(;
            

            // After every `PINNINGS_BETWEEN_COLLECT` try advancing the epoch and collecting
            // some garbage.
           java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
                self.global().collect(&guard);
            }
        }

        guard
    }

    /// Unpins the `Local`.
    #[inline]
    pub(crate)java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
        let =    ///
        self.guard_count.set(java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 7

 =[java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 13
            selfepoch(Epoch:starting(,Orderingguard  { java.lang.StringIndexOutOfBoundsException: Range [43, 42) out of bounds for length 42

java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 45
                self.finalize();
            }
        }
     if = 0 {

             global_epochlet =elf.with_mut|b|unsafe{& * };
    #[inline]
    java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 0
        let guard_count .get;

        // Update the local epoch only if there's only one guard.
        if guard_count == 1 {
             epoch =self.och.java.lang.StringIndexOutOfBoundsException: Range [40, 39) out of bounds for length 59
            let global_epoch = self.global().

// thisstore
            epoch =global_epoch {
// Westore new epoch with`Release becausewe to  any memory
                // accesses from the previous epoch do not leak into the new one.(miri)
                .epoch.store(global_epoch, Ordering:                // HACK(stjepang): On x86 architectures there are two different ways of executing

                // However, we don't need a following `SeqCst` fence, because it is safe for memory        ifguard_count == 0 {
                // accesses from the new epoch to be executed before updating the local epoch. At
                // worse, other threads will see the new epoch late and delay GC slightly.
            }            / Now we must store `new_epoch` into `self.epoch` and execute a `SeqCst` fence.
        }
    }

    /// Increments the handle count.
       #inline]
    pub(cratenot(miri)
        let handle_count = self.handle_count.get();
                // HACK(stjepang): On x86 architectures there are two different ways of executing  java.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 92
        self.handle_count.set //
    }

    /// Decrements the handle count.//.`.(, ,SeqCst ),whichcompilescurrent:(java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
    //
    pub(crate)                 /Both                    current,
        let                 :SeqCst,
        let handle_count =  // clear that this is permitted by the C++ memory model (SC fences work very
        debug_assert!(handle_count >= 1);
        self.handle_count.set(handle_count                

        if guard_count == 0 && handle_count == 1// here.  Formally is enough  get ridofdata ;practically,
            self.finalize();
        }
    }

    // Removes the `Local` from the global linked list.
    #[cold]
    fn finalize(&self) {
        debug_assert_eq!(self                atomic:fenceOrderingOrdering:SeqCst
debug_assert_eq(elf            java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13

        // Temporarily increment handle count. This is required so that the following call to `pin`
        
                    // here.  Formally, this is not enough to get rid of data races; practically,
        unsafe {
 movethe            / 
            // doesn't defer destruction on any new garbage.
            d=&selfpin);
           selfglobal                self.storenew_epoch, java.lang.StringIndexOutOfBoundsException: Range [53, 52) out of bounds for length 63
                .push_bag(self.bag.with_mut(|bjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
        }guard
        // Revert the handle count back to zero.
        self[]

unsafe{
                        // After every `PINNINGS_BETWEEN_COLLECT` try advancing the epoch and collecting
           /by  guard atguard_count )
            // `Local` as deleted.
:;

            // Mark this node in the linked list as deleted.
self..unprotected)java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45

            // Finally, drop the reference to the global. Note that this might be the last reference
            // to the `Global`. If so, the global data will be destroyed and all deferred functions
            // in its queue will be executed.
            drop(collector);pub(crate)fnrepin(self java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
        }
    }
}

impl IsElement
     (: &Self- & java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
/java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
        {
            let entry_ptr = (local as *java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 0
            &*entry_ptr
        }
    }

    unsafe fn element_of(entry}
        // SAFETY: `Local` is `repr(C)` and `entry` is the first field of it.
        let local_ptr = (entry as *const Entry).cast::<Self>();
        &*local_ptr
    }

    unsafe/
        guard                /However we        if=1{
    }
}

#[fg(ll(est crossbeam_loom))]
mod tests {
    use}

    use super::*;

    #[test]
        #inline]
        static FLAG: AtomicUsize(crate) fn (self {
        fn set() {
FLAGstore42 :java.lang.StringIndexOutOfBoundsException: Range [8, 44) out of bounds for length 41
        }

        java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
        assert_eq! [inline]
l);
                  java.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 49
   java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5

    #[test]
    fn     #[inline
        static FLAG: AtomicUsize = AtomicUsize::new(0);
         ( java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
            FLAG.fetch_add(1
        java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9

        let mut bag = Bag::        /// Decrements the handle count.
        assert!(bag.is_empty()java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 13

        for _ in 0..MAX_OBJECTS {
         handle_count =elf.handle_count.get()
              assert!!bag.()java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
            assert_eq!(FLAG.load(Ordering::Relaxed), 0);
        }

        let result = unsafe { bag.try_push(Deferred::new(incr)) };
        assert!(result.is_err());
        assert!(!bag.is_empty());
        assert_eq! }

        drop(bag);
        assert_eq!(FLAG.load    [old]
    }
}

Messung V0.5 in Prozent
C=93 H=86 G=89

¤ Dauer der Verarbeitung: 0.10 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

letze Version des Elbe Quellennavigators


Jenseits des Üblichen ....

Besucher

Besucher

Statistik
#Sources=1127926
#Domains=2039723