Skip to content

mutex example initialization procedure appears to be incorrectly synchronizedΒ #115

@soooch

Description

@soooch

let mutex = if shmem.is_owner() {
is_init.store(0, Ordering::Relaxed);
// Initialize the mutex
let (lock, _bytes_used) = unsafe {
Mutex::new(
raw_ptr, // Base address of Mutex
raw_ptr.add(Mutex::size_of(Some(raw_ptr))), // Address of data protected by mutex
)
.unwrap()
};
is_init.store(1, Ordering::Relaxed);
lock
} else {
// wait until mutex is initialized
while is_init.load(Ordering::Relaxed) != 1 {}
// Load existing mutex
let (lock, _bytes_used) = unsafe {
Mutex::from_existing(
raw_ptr, // Base address of Mutex
raw_ptr.add(Mutex::size_of(Some(raw_ptr))), // Address of data protected by mutex
)
.unwrap()
};
lock
};

    let mutex = if shmem.is_owner() {
        // is_init.store(0, Ordering::Relaxed); // not actually needed
        // Initialize the mutex
        let (lock, _bytes_used) = unsafe {
            Mutex::new(
                raw_ptr,                                    // Base address of Mutex
                raw_ptr.add(Mutex::size_of(Some(raw_ptr))), // Address of data protected by mutex
            )
            .unwrap()
        };
        // is_init.store(1, Ordering::Relaxed); // relaxed wouldn't restrict reordering of mutex init unless i'm missing something
        is_init.store(1, Ordering::Release);
        lock
    } else {
        // wait until mutex is initialized
        // while is_init.load(Ordering::Relaxed) != 1 {} // need acquire for release store to is_init to synchronize-with load
        // could also do a relaxed loop with a acquire fence, but that adds an extra instruction in the common case
        while is_init.load(Ordering::Acquire) != 1 {
            std::hint::spin_loop();
        }
        // Load existing mutex
        let (lock, _bytes_used) = unsafe {
            Mutex::from_existing(
                raw_ptr,                                    // Base address of Mutex
                raw_ptr.add(Mutex::size_of(Some(raw_ptr))), // Address of data  protected by mutex
            )
            .unwrap()
        };
        lock
    };

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions