| 43 | } |
| 44 | |
| 45 | fn increment_value(shmem_flink: &str, thread_num: usize) { |
| 46 | // Create or open the shared memory mapping |
| 47 | let shmem = match ShmemConf::new().size(4096).flink(shmem_flink).create() { |
| 48 | Ok(m) => m, |
| 49 | Err(ShmemError::LinkExists) => ShmemConf::new().flink(shmem_flink).open().unwrap(), |
| 50 | Err(e) => { |
| 51 | eprintln!( |
| 52 | "Unable to create or open shmem flink {} : {}", |
| 53 | shmem_flink, e |
| 54 | ); |
| 55 | return; |
| 56 | } |
| 57 | }; |
| 58 | |
| 59 | let mut raw_ptr = shmem.as_ptr(); |
| 60 | let is_init: &mut AtomicU8; |
| 61 | |
| 62 | unsafe { |
| 63 | is_init = &mut *(raw_ptr as *mut u8 as *mut AtomicU8); |
| 64 | raw_ptr = raw_ptr.add(8); |
| 65 | }; |
| 66 | |
| 67 | // Initialize or wait for initialized mutex |
| 68 | let mutex = if shmem.is_owner() { |
| 69 | is_init.store(0, Ordering::Relaxed); |
| 70 | // Initialize the mutex |
| 71 | let (lock, _bytes_used) = unsafe { |
| 72 | Mutex::new( |
| 73 | raw_ptr, // Base address of Mutex |
| 74 | raw_ptr.add(Mutex::size_of(Some(raw_ptr))), // Address of data protected by mutex |
| 75 | ) |
| 76 | .unwrap() |
| 77 | }; |
| 78 | is_init.store(1, Ordering::Relaxed); |
| 79 | lock |
| 80 | } else { |
| 81 | // wait until mutex is initialized |
| 82 | while is_init.load(Ordering::Relaxed) != 1 {} |
| 83 | // Load existing mutex |
| 84 | let (lock, _bytes_used) = unsafe { |
| 85 | Mutex::from_existing( |
| 86 | raw_ptr, // Base address of Mutex |
| 87 | raw_ptr.add(Mutex::size_of(Some(raw_ptr))), // Address of data protected by mutex |
| 88 | ) |
| 89 | .unwrap() |
| 90 | }; |
| 91 | lock |
| 92 | }; |
| 93 | |
| 94 | // Loop until mutex data reaches 10 |
| 95 | loop { |
| 96 | // Scope where mutex will be locked |
| 97 | { |
| 98 | let mut guard = mutex.lock().unwrap(); |
| 99 | // Cast mutex data to &mut u8 |
| 100 | let val: &mut u8 = unsafe { &mut **guard }; |
| 101 | if *val > 5 { |
| 102 | println!("[thread#{}] done !", thread_num); |