Skip to content

Commit db489d9

Browse files
committed
add more special examples
1 parent 6b28540 commit db489d9

13 files changed

+368
-38
lines changed

special/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,22 @@ edition = "2021"
77

88
[dependencies]
99
async-lock = "2.5.0"
10+
async-oneshot = "0.5.0"
11+
atomic_float = "0.1.0"
12+
catty = "0.1.5"
1013
concurrent-queue = "1.2.4"
1114
dashmap = "5.4.0"
1215
event-listener = "2.5.3"
16+
evmap = "10.0.2"
17+
flurry = "0.4.0"
18+
oneshot = "0.1.5"
19+
portable-atomic = { version = "0.3", features=["float"] }
1320
process_lock = "0.1.0"
1421
sharded-slab = "0.1.4"
22+
simple-mutex = "1.1.5"
1523
slab = "0.4.7"
1624
smol = "1.2.5"
25+
triggered = "0.1.2"
1726
try-lock = "0.2.3"
27+
waitgroup = "0.1.2"
28+
wg = "0.3.1"

special/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
pub mod oslock;
2-
pub mod oneshot;
2+
pub mod oneshots;
33
pub mod map;
44
pub mod primitive;
55
pub mod notify;
66
pub mod queue;
77

88
pub use oslock::*;
9-
pub use oneshot::*;
9+
pub use oneshots::*;
1010
pub use map::*;
1111
pub use primitive::*;
1212
pub use notify::*;

special/src/main.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,35 @@ fn main() {
1212
slab_example();
1313

1414
event_listener_example();
15+
triggered_example();
1516

1617
hashmap_example();
18+
flurry_hashmap();
19+
flurry_hashset();
20+
evmap_example();
21+
1722
concurrent_queue_example();
1823

1924
async_lock_mutex();
25+
async_lock_rwlock();
26+
async_lock_barrier();
27+
async_lock_semaphore();
28+
29+
portable_atomic_i128();
30+
portable_atomic_u128();
31+
portable_atomic_f64();
32+
atomic_float_example();
33+
34+
simple_mutex_example();
35+
36+
oneshot_example();
37+
async_oneshot_example();
38+
catty_example();
39+
40+
waitgroup_example();
41+
wg_example();
42+
2043
}
44+
45+
46+
// lockfree

special/src/map.rs

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
use dashmap::DashMap;
12
use std::sync::Arc;
23
use std::thread;
3-
use dashmap::DashMap;
44

55
pub fn hashmap_example() {
66
let map = Arc::new(DashMap::new());
@@ -11,26 +11,97 @@ pub fn hashmap_example() {
1111
map1.insert(2, 3);
1212
});
1313

14-
1514
let map2 = map.clone();
1615
let rhandle = thread::spawn(move || {
17-
1816
loop {
1917
if let Some(v) = map2.get(&1) {
2018
println!("get value {} for key 1", *v);
2119
break;
22-
}
20+
}
2321
}
2422

2523
loop {
2624
if let Some(v) = map2.get(&2) {
2725
println!("get value {} for key 2", *v);
2826
break;
29-
}
27+
}
3028
}
3129
});
3230

3331
whandle.join().unwrap();
3432
rhandle.join().unwrap();
33+
}
34+
35+
pub fn flurry_hashmap() {
36+
let map = flurry::HashMap::new();
37+
38+
assert_eq!(map.pin().insert(37, "a"), None);
39+
assert_eq!(map.pin().is_empty(), false);
40+
}
41+
42+
pub fn flurry_hashset() {
43+
// Initialize a new hash set.
44+
let books = flurry::HashSet::new();
45+
let guard = books.guard();
46+
47+
// Add some books
48+
books.insert("Fight Club", &guard);
49+
books.insert("Three Men In A Raft", &guard);
50+
books.insert("The Book of Dust", &guard);
51+
books.insert("The Dry", &guard);
52+
53+
// Check for a specific one.
54+
if !books.contains(&"The Drunken Botanist", &guard) {
55+
println!("We don't have The Drunken Botanist.");
56+
}
57+
58+
// Remove a book.
59+
books.remove(&"Three Men In A Raft", &guard);
60+
61+
// Iterate over everything.
62+
for book in books.iter(&guard) {
63+
println!("{}", book);
64+
}
65+
}
66+
67+
pub fn evmap_example() {
68+
let (book_reviews_r, mut book_reviews_w) = evmap::new();
3569

70+
let readers: Vec<_> = (0..4)
71+
.map(|_| {
72+
let r = book_reviews_r.clone();
73+
thread::spawn(move || {
74+
loop {
75+
let l = r.len();
76+
if l == 0 {
77+
thread::yield_now();
78+
} else {
79+
// the reader will either see all the reviews,
80+
// or none of them, since refresh() is atomic.
81+
assert_eq!(l, 4);
82+
break;
83+
}
84+
}
85+
})
86+
})
87+
.collect();
88+
89+
// do some writes
90+
book_reviews_w.insert("Adventures of Huckleberry Finn", "My favorite book.");
91+
book_reviews_w.insert("Grimms' Fairy Tales", "Masterpiece.");
92+
book_reviews_w.insert("Pride and Prejudice", "Very enjoyable.");
93+
book_reviews_w.insert("The Adventures of Sherlock Holmes", "Eye lyked it alot.");
94+
// expose the writes
95+
book_reviews_w.refresh();
96+
97+
// you can read through the write handle
98+
assert_eq!(book_reviews_w.len(), 4);
99+
100+
// the original read handle still works too
101+
assert_eq!(book_reviews_r.len(), 4);
102+
103+
// all the threads should eventually see .len() == 4
104+
for r in readers.into_iter() {
105+
assert!(r.join().is_ok());
106+
}
36107
}

special/src/notify.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,22 @@ pub fn event_listener_example() {
4545

4646
println!("flag is set");
4747
}
48+
49+
pub fn triggered_example() {
50+
smol::block_on(async {
51+
let (trigger, listener) = triggered::trigger();
52+
53+
let task = smol::spawn(async {
54+
// Blocks until `trigger.trigger()` below
55+
listener.await;
56+
57+
println!("Triggered async task");
58+
});
59+
60+
// This will make any thread blocked in `Listener::wait()` or async task awaiting the
61+
// listener continue execution again.
62+
trigger.trigger();
63+
64+
let _ = task.await;
65+
})
66+
}

special/src/oneshot.rs

Lines changed: 0 additions & 2 deletions
This file was deleted.

special/src/oneshots.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use std::thread;
2+
3+
pub fn oneshot_example() {
4+
let (sender, receiver) = oneshot::channel::<i32>();
5+
let sender = thread::spawn(move || {
6+
sender.send(1).unwrap();
7+
});
8+
let receiver = thread::spawn(move || {
9+
let v = receiver.recv().unwrap();
10+
println!("get value {}", v);
11+
});
12+
sender.join().unwrap();
13+
receiver.join().unwrap();
14+
}
15+
16+
pub fn async_oneshot_example() {
17+
let (mut sender, receiver) = async_oneshot::oneshot();
18+
smol::block_on(async {
19+
sender.send(1).unwrap();
20+
});
21+
22+
smol::block_on(async {
23+
let v = receiver.try_recv().unwrap();
24+
println!("get value {}", v);
25+
});
26+
}
27+
28+
pub fn catty_example() {
29+
let (sender, mut receiver) = catty::oneshot();
30+
let sender = thread::spawn(move || {
31+
sender.send(1).unwrap();
32+
});
33+
let receiver = thread::spawn(move || {
34+
let v = receiver.try_recv().unwrap();
35+
if v.is_some() {
36+
println!("get value {}", v.unwrap());
37+
}
38+
39+
});
40+
sender.join().unwrap();
41+
receiver.join().unwrap();
42+
}

special/src/primitive/async_lock_example.rs

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use async_lock::*;
2+
use std::sync::Arc;
3+
use std::thread;
4+
5+
pub fn async_lock_mutex() {
6+
let lock = Arc::new(Mutex::new(0));
7+
8+
let lock1 = lock.clone();
9+
smol::block_on(async {
10+
let mut guard = lock1.lock().await;
11+
*guard += 1;
12+
});
13+
14+
let lock2 = lock.clone();
15+
smol::block_on(async {
16+
let guard = lock2.lock().await;
17+
println!("lock2 {}", *guard);
18+
});
19+
}
20+
21+
pub fn async_lock_rwlock() {
22+
let lock = Arc::new(RwLock::new(0));
23+
24+
let lock1 = lock.clone();
25+
smol::block_on(async {
26+
let mut guard = lock1.write().await;
27+
*guard += 1;
28+
});
29+
30+
let lock2 = lock.clone();
31+
smol::block_on(async {
32+
let guard = lock2.read().await;
33+
println!("lock2 {}", *guard);
34+
});
35+
}
36+
37+
pub fn async_lock_barrier() {
38+
let barrier = Arc::new(Barrier::new(5));
39+
40+
thread::scope(|s| {
41+
for _ in 0..5 {
42+
let barrier = barrier.clone();
43+
s.spawn(move || {
44+
smol::block_on(async {
45+
println!("before wait");
46+
barrier.wait().await;
47+
println!("after wait");
48+
});
49+
});
50+
}
51+
});
52+
}
53+
54+
pub fn async_lock_semaphore() {
55+
let s = Arc::new(Semaphore::new(2));
56+
57+
let _g1 = s.try_acquire_arc().unwrap();
58+
let g2 = s.try_acquire_arc().unwrap();
59+
60+
assert!(s.try_acquire_arc().is_none());
61+
drop(g2);
62+
assert!(s.try_acquire_arc().is_some());
63+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use portable_atomic::*;
2+
use std::sync::atomic::Ordering::Relaxed;
3+
4+
pub fn portable_atomic_i128() {
5+
let mut some_var = AtomicI128::new(10);
6+
assert_eq!(*some_var.get_mut(), 10);
7+
*some_var.get_mut() = 5;
8+
assert_eq!(some_var.load(Ordering::SeqCst), 5);
9+
10+
assert_eq!(some_var.load(Ordering::Relaxed), 5);
11+
}
12+
13+
pub fn portable_atomic_u128() {
14+
let mut some_var = AtomicU128::new(10);
15+
assert_eq!(*some_var.get_mut(), 10);
16+
*some_var.get_mut() = 5;
17+
assert_eq!(some_var.load(Ordering::SeqCst), 5);
18+
19+
assert_eq!(some_var.load(Ordering::Relaxed), 5);
20+
}
21+
22+
pub fn portable_atomic_f32() {
23+
let mut some_var = AtomicF32::new(10.0);
24+
assert_eq!(*some_var.get_mut(), 10.0);
25+
*some_var.get_mut() = 5.0;
26+
assert_eq!(some_var.load(Ordering::SeqCst), 5.0);
27+
28+
assert_eq!(some_var.load(Ordering::Relaxed), 5.0);
29+
}
30+
31+
pub fn portable_atomic_f64() {
32+
let mut some_var = AtomicF64::new(10.0f64);
33+
assert_eq!(*some_var.get_mut(), 10.0);
34+
*some_var.get_mut() = 5.0;
35+
assert_eq!(some_var.load(Ordering::SeqCst), 5.0);
36+
37+
assert_eq!(some_var.load(Ordering::Relaxed), 5.0);
38+
}
39+
40+
pub fn atomic_float_example() {
41+
let some_var = atomic_float::AtomicF32::new(800.0f32);
42+
some_var.fetch_add(30.0, Relaxed);
43+
some_var.fetch_sub(-55.0, Relaxed);
44+
some_var.fetch_neg(Relaxed);
45+
46+
assert_eq!(some_var.load(Relaxed), -885.0);
47+
48+
let some_var = atomic_float::AtomicF64::new(800.0f64);
49+
some_var.fetch_add(30.0, Relaxed);
50+
some_var.fetch_sub(-55.0, Relaxed);
51+
some_var.fetch_neg(Relaxed);
52+
53+
assert_eq!(some_var.load(Relaxed), -885.0);
54+
}

0 commit comments

Comments
 (0)