I'm working to understand how Rust 1.62 avoid allocations for futex-based locks. I think the summary is this:
1. A mutex is a u8. The mutex fast path is locking via atomic ops to set a bit.
2. Contention is resolved by adding the blocked thread into a wait queue. The queue is allocated/discovered via a global hash table, keyed by the address of the mutex. The mutex keeps a stable address while locked, as the lock holds shared ownership and so the mutex cannot be moved for the duration.
I ported a POSIX semaphore wrapper from C++ to Rust, and needed an extra allocation for the same reason, to get an int with a stable address. Unfortunately this technique won't work for semaphores, they need to be async-signal safe. So I'm still stuck with `Pin<Box<UnsafeCell<sem_t>>>` where in C++ it's just `sem_t` and a deleted move constructor.
Anyways this is a lot of hoops to jump through to avoid non-movable types, hope it's worth it!