Search code examples
rustmutexcompile-time

How is it possible for a Mutex to be constructed at compile time?


It is now possible to compile the following code:

use std::sync::Mutex;

static GUARD: Mutex<()> = Mutex::new();

I am trying to understand how this is possible.

My understanding of const functionality in Rust is that there is a subset of the language that is available to you at compile time. The classic example being that 1+1 can be calculated at compile time, so why wait until runtime to pay the cost of the addition. Accepting this, then if you have a function like

const fn two() -> u32 {
   1+1
}

and it is called somewhere, then again the compiler should do this up front, inline the value and save the function call. The subset of const-callable code is growing over time, but there is obviously a hard limit on this of any operations requiring runtime input.

A Mutex strikes me as something requiring runtime input. It relies on operating system specific system calls to allow synchronisation to occur between threads. Although the compiler knows which OS it is targeting, I don't see how this initialisation can happen at compile time without requiring something at runtime at all.


Solution

  • On modern operating systems, mutexes are not special OS-level objects - they're just memory regions accessed by atomic operations (which are CPU instructions) in a way that guarentees exclusive access.

    The only time that the OS enters the picture is when dealing with waiting. Threads trying to access a locked mutex need to tell the OS to block and schedule other tasks, and threads releasing a mutex may need to tell the OS to wake up the waiting threads.

    So for initializing a mutex, the OS doesn't need to be involved. You don't even need atomic operations, as the initializer has exclusive access.

    For Linux, this is done through the futex system call. The two basic operations of it are to atomically check a memory address and wait, or to wake up any other threads waiting on a memory address - neither of which involve a file descriptor or any other OS-level object.