()
| 641 | #[test] |
| 642 | #[cfg_attr(miri, ignore)] |
| 643 | fn shared_memory_wait_notify() -> Result<()> { |
| 644 | const THREADS: usize = 8; |
| 645 | const COUNT: usize = 100_000; |
| 646 | |
| 647 | let mut config = Config::new(); |
| 648 | config.shared_memory(true); |
| 649 | let engine = Engine::new(&config)?; |
| 650 | let memory = SharedMemory::new(&engine, MemoryType::shared(1, 1))?; |
| 651 | let data = unsafe { AtomicU32::from_ptr(memory.data().as_ptr().cast_mut().cast()) }; |
| 652 | let locked = unsafe { AtomicU32::from_ptr(memory.data().as_ptr().add(4).cast_mut().cast()) }; |
| 653 | |
| 654 | // Note that `SeqCst` is used here to not think much about the orderings |
| 655 | // here, and it also somewhat more closely mirrors what's happening in wasm. |
| 656 | let lock = || { |
| 657 | while locked.swap(1, SeqCst) == 1 { |
| 658 | memory.atomic_wait32(0, 1, None).unwrap(); |
| 659 | } |
| 660 | }; |
| 661 | let unlock = || { |
| 662 | locked.store(0, SeqCst); |
| 663 | memory.atomic_notify(0, 1).unwrap(); |
| 664 | }; |
| 665 | |
| 666 | std::thread::scope(|s| { |
| 667 | for _ in 0..THREADS { |
| 668 | s.spawn(|| { |
| 669 | for _ in 0..COUNT { |
| 670 | lock(); |
| 671 | let next = data.load(SeqCst) + 1; |
| 672 | data.store(next, SeqCst); |
| 673 | unlock(); |
| 674 | } |
| 675 | }); |
| 676 | } |
| 677 | }); |
| 678 | |
| 679 | assert_eq!(data.load(SeqCst), (THREADS * COUNT) as u32); |
| 680 | |
| 681 | Ok(()) |
| 682 | } |
| 683 | |
| 684 | #[test] |
| 685 | #[cfg_attr(miri, ignore)] |
nothing calls this directly
no test coverage detected