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
//! flize is an implementation of epoch-based lock-free resource reclamation. //! The core is based around the paper "Practical lock-freedom" by Keir Fraster //! although many modifications have been made to adapt the scheme to perform well on //! on modern hardware and scale to a high degree. //! //! This crate is useful if you have resources that require destruction in a //! concurrent environment and you don't want to pay the price of locking. //! //! flize attempts to encourage simplicity and avoid implicit global state. //! Additionally we try to reduce the amount of hidden gotchas and ways to shoot yourself in the foot. //! //! A basic understanding of the previously mentioned paper and lock-free memory management //! is assumed throughout this documentation. If it isn't clearly explained here //! it's probably well defined in the paper. If not, please submit an issue and we will try to add documentation. //! //! The core workflow of this library involves a couple of different types. //! First up you've got `Collector` and `Shield`, they are the gateway to interacting with the core functionality. //! A collector keeps track of what threads are reading protected pointers and which aren't. It does this //! by requiring allowing the user to create `Shield`s which act as as sort of guard. The creation //! and destruction of this type interacts with the internal bookkeeping in the `Collector`. //! The existance of at least one `Shield` implies that the thread is in a critical section //! and may access protected pointers. //! //! Shields are in turn needed to load `Atomic`s which simply boil down to an atomic pointer. //! Upon loading an `Atomic` you get a `Shared` which is a pointer type bounded by the lifetime of the shield. //! This is an attempt to prevent you from using a pointer without being in a critical section. //! `Atomic` implements all the common atomic operations for reading and modification such as `load`, `store` and `compare_and_swap`. //! When you remove all pointers to an object from shared memory it will be safe to destroy //! after all threads that could possibly have a reference have exited their critical sections (dropped all their shields). //! This can be accomplished by calling `Shield::defer` and supplying a closure. This closure //! will then be executed once all threads currently in a critical section have exited it at least once. //! //! flize also handles a couple of other things that vastly improves quality of life //! and simplicity for users compared to `crossbeam-epoch`. For example flize provides you //! with full support for low and high bit pointer tags. It takes this one step further //! and allows for arbitrary structs that can be serialized to an array of bits to //! be used as tags. The library will handle reading, writing and stripping these tags from and to pointers //! along with serialization for you with a set of helper methods on `Shared` for interacting with tags ergonomically. mod atomic; mod barrier; mod cache_padded; mod deferred; mod ebr; mod lazy; mod mutex; mod queue; mod shared; mod tag; mod thread_local; pub use atomic::Atomic; pub use cache_padded::CachePadded; pub use ebr::{ unprotected, Collector, CowShield, FullShield, Local, Shield, ThinShield, UnprotectedShield, }; pub use shared::Shared; pub use tag::{NullTag, Tag};