[−][src]Crate tearor
tearor
provides the TearCell
, a (barely) thread-safe lock-free cell
type providing tearing access to any type which is Pod
.
Tearing access refers to when multiple smaller, separate read or write operations are used to perform a larger unit of work. For example, if you wrote to a &mut u32 by performing 4 writes, one to each byte, or vice-versa.
TearCell uses the same idea, but with atomics. If your T
is too large to
fit inside an atomic, then TearCell
will split it over a few operations.
Needless to say, this means calls to TearCell::load
, TearCell::store
,
(etc) are not atomic (nor do they provide any guarantees about
ordering), however every individual operation the TearCell performs is
atomic (with the weakest ordering we can get our hands on), which is enough
to avoid data races.
It's essentially a tool for turning data races into data corruption. If the
lack of synchronization would cause a data race (e.g. with UnsafeCell), then
TearCell
is very likely to corrupt your data.
However, if this does not matter to you for one reason or another (examples:
your synchronization is performed externally, you want to perform an
optimistic read, all threads are writing the same value, or you miss the fun
you had debugging data corruption issues in C++), then TearCell
might be
what you want.
This library might not be for you if...
-
You aren't sure if tearing is acceptable for your use case, or aren't sure you understand what it means. You should just use a
Mutex<T>
orRwLock<T>
then. These are much harder to misuse, and can't corrupt your data. -
You don't require
Sync
-- e.g.Cell<T>
would be acceptable for your use case. In this case, useCell<T>
. -
Your
T
is notSend
. In this case,TearCell<T>
will be neitherSend
norSync
, which makes it pretty useless. -
Your
T
is not plain-old-data -- e.g. it has padding bytes, isn'tCopy
, contains references, has initialized bit patterns which cause undefined behavior, etc. (Example: #[repr(Rust)] types, bools, enums, char, references...). -
Your
T
(is POD and) fits inside one of the atomic types incore::sync::atomic
. TearCell will literally be worse in every way than just performingRelaxed
loads/stores to that type. -
You need to compile for a target which doesn't support
AtomicU8
orAtomicUsize
. Currently this is unsupported, but I'd accept a PR adding the#[cfg]
needed. -
T
is fairly large, but only has a 1-byte alignment, or has an odd size. (For example,[u8; 127]
). For these the performance will be suboptimal, but this may be improved in the future.
Structs
TearCell |
|
Traits
Pod | Marker trait for "plain old data". |
Zeroable | Trait for types that can be safely created with
|