Create a new module
std::sync::pinned for OS synchronization primitives which make use of the
Pin dialect instead of relying on boxing.
The current synchronization primitives at
std::sync box the OS primitives for some OSes, including all Posix-compliant. This is suboptimal as it increases the possibility of cache misses, and adds overhead to creation of these primitives.
With the new
Pin type, we can expose the primitives directly and have the functions simply take
This gives more flexibility as it is possible to have, for example,
Arc<Mutex<T>> without double-boxing the
For the following types:
Pinned versions are available at the module
std::sync::pinned. These versions are all
In all methods of these pinned versions a
self: Pin<&Self> argument is taken, therefore the type must be constructed with, for example,
In order to initialize a
pinned::Mutex, for example, one of these can be used:
// Directly initialize using ergonomic constructors let boxed_mutex: Pin<Box<Mutex<T>>> = Mutex::boxed(...); let arc_mutex: Pin<Arc<Mutex<T>>> = Mutex::arc(...); // Explicitly initialize after creation with a custom constructor // Nothing here is unsafe, the library checks for initialization let mut mutex: Pin<Box<Mutex<T>>> = Box::pin(Mutex::uninit(...)); mutex.as_mut().init();
sys_common already has a pretty good infrastructure for implementing this.
- The explicit initialization is done by first creating the structure using
uninit(value: T) -> Self, then calling
init(self: Pin<&mut Self>).
- The library adds the necessary assertions to make this pattern safe. Using before
panic!. In particular, the implementation can use an
Optionto wrap the OS primitive. The assertions can be placed such that they are inlined, so if one method is used after another, the assertion can be optimized away for the second method.
- Adds further complexity to the
- Alternative for the explicit initialization: have unsafe
uninit(). This can remove assertion overhead but can lead to some hard to detect undefined behaviour, as in POSIX - for example - this would cause mutexes to work as normal until a double lock happens, which would cause undefined behaviour.
Replace the primitives with
parking_lot. This has been proposed in the past and has its fair share of drawbacks, such as non-trivial space overhead which can be a deal breaker for some applications.
- System languages such as C and C++ expose the OS primitives with thin wrappers, without the boxing our current implementation uses. This is possible without
Pinas these languages have different move semantics, on which types are not moved by default.
- Pin + Arc + Mutex - The Rust Programming Language Forum
syncpackage for the Linux kernel: linux/mod.rs at rust · Rust-for-Linux/linux · GitHub
Oncebe moved to
pinnedfor consistency? The current implementation does not box any primitives, however if we were to use
pthread_once_tin the future, it would be necessary.
- Lints for double boxing (suggesting