1extern crate atom;
16
17use atom::*;
18use std::mem;
19use std::sync::{atomic::Ordering, Arc, Barrier};
20use std::thread;
21
22const THREADS: usize = 100;
23
24#[derive(Debug)]
25struct Link {
26 next: AtomSetOnce<Box<Link>>,
27}
28
29impl Drop for Link {
30 fn drop(&mut self) {
31 while let Some(mut h) = self.next.atom().take(Ordering::Acquire) {
33 self.next = mem::replace(&mut h.next, AtomSetOnce::empty());
34 }
35 }
36}
37
38fn main() {
39 let b = Arc::new(Barrier::new(THREADS + 1));
40
41 let head = Arc::new(Link {
42 next: AtomSetOnce::empty(),
43 });
44
45 for _ in 0..THREADS {
46 let b = b.clone();
47 let head = head.clone();
48 thread::spawn(move || {
49 let mut hptr = &*head;
50
51 for _ in 0..10_000 {
52 let mut my_awesome_node = Box::new(Link {
53 next: AtomSetOnce::empty(),
54 });
55
56 loop {
57 while let Some(h) = hptr.next.get(Ordering::Acquire) {
58 hptr = h;
59 }
60
61 my_awesome_node =
62 match hptr.next.set_if_none(my_awesome_node, Ordering::Release) {
63 Some(v) => v,
64 None => break,
65 };
66 }
67 }
68 b.wait();
69 });
70 }
71
72 b.wait();
73
74 let mut hptr = &*head;
75 let mut count = 0;
76 while let Some(h) = hptr.next.get(Ordering::Acquire) {
77 hptr = h;
78 count += 1;
79 }
80 println!(
81 "Using {} threads we wrote {} links at the same time!",
82 THREADS, count
83 );
84}