|
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
};
shared_memory/examples/mutex.rs
Lines 65 to 89 in fda4134