Guest User

Untitled

a guest
Jan 3rd, 2022
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 1.77 KB | None | 0 0
  1. use std::sync::atomic::{AtomicBool, Ordering};
  2. use std::thread;
  3.  
  4. #[cfg(not(feature = "acqrel"))]
  5. const ACK: Ordering = Ordering::Relaxed;
  6. #[cfg(not(feature = "acqrel"))]
  7. const REL: Ordering = Ordering::Relaxed;
  8. #[cfg(feature = "acqrel")]
  9. const ACK: Ordering = Ordering::Acquire;
  10. #[cfg(feature = "acqrel")]
  11. const REL: Ordering = Ordering::Release;
  12.  
  13. static FLAG: AtomicBool = AtomicBool::new(false);
  14. static mut SHARED_VALUE: u32 = 0;
  15.  
  16. fn do_busy_work(v: *mut i32) {
  17.     loop {
  18.         let i: i32 = rand::random();
  19.         unsafe {
  20.             std::ptr::write_volatile(v, i);
  21.         }
  22.         if (i & 7) == 0 {
  23.             return;
  24.         }
  25.     }
  26. }
  27.  
  28. const INCREMENTS: usize = 10_000_000;
  29. fn increment_shared_value() {
  30.     let mut count = 0;
  31.     while count < INCREMENTS {
  32.         let mut v = 0;
  33.         do_busy_work(&mut v as _);
  34.  
  35.         if FLAG
  36.             .compare_exchange(false, true, ACK, Ordering::Relaxed)
  37.             .is_ok()
  38.         {
  39.             // increment
  40.             unsafe {
  41.                 SHARED_VALUE += 1;
  42.             }
  43.             // store
  44.             FLAG.store(false, REL);
  45.             // counter
  46.             count += 1;
  47.         }
  48.     }
  49. }
  50.  
  51. pub fn main() {
  52.     let threads_count = std::env::args()
  53.         .nth(1)
  54.         .unwrap_or_else(|| "2".into())
  55.         .parse()
  56.         .expect("the first argument to be a thread count");
  57.  
  58.     let mut threads = Vec::with_capacity(threads_count);
  59.  
  60.     loop {
  61.         unsafe {
  62.             SHARED_VALUE = 0;
  63.         }
  64.  
  65.         for _ in 0..threads_count {
  66.             threads.push(thread::spawn(increment_shared_value));
  67.         }
  68.  
  69.         for t in threads.drain(..) {
  70.             t.join().unwrap();
  71.         }
  72.         println!("shared value = {}", unsafe { SHARED_VALUE });
  73.     }
  74. }
  75.  
Advertisement
Add Comment
Please, Sign In to add comment