summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/basic.rs2
-rw-r--r--examples/dining_philosophers.rs14
-rw-r--r--examples/dining_philosophers_retry.rs75
-rw-r--r--examples/double_mutex.rs10
-rw-r--r--examples/fibonacci.rs29
-rw-r--r--examples/list.rs8
6 files changed, 123 insertions, 15 deletions
diff --git a/examples/basic.rs b/examples/basic.rs
index 1d611d3..b9c5641 100644
--- a/examples/basic.rs
+++ b/examples/basic.rs
@@ -23,5 +23,5 @@ fn main() {
let key = ThreadKey::get().unwrap();
let data = DATA.lock(key);
- println!("{}", *data);
+ println!("{data}");
}
diff --git a/examples/dining_philosophers.rs b/examples/dining_philosophers.rs
index 35aa330..dc4dd51 100644
--- a/examples/dining_philosophers.rs
+++ b/examples/dining_philosophers.rs
@@ -1,6 +1,6 @@
use std::{thread, time::Duration};
-use happylock::{LockCollection, Mutex, ThreadKey};
+use happylock::{collection, Mutex, ThreadKey};
static PHILOSOPHERS: [Philosopher; 5] = [
Philosopher {
@@ -50,8 +50,8 @@ impl Philosopher {
thread::sleep(Duration::from_secs(1));
// safety: no philosopher asks for the same fork twice
- let forks =
- unsafe { LockCollection::new_unchecked([&FORKS[self.left], &FORKS[self.right]]) };
+ let forks = [&FORKS[self.left], &FORKS[self.right]];
+ let forks = unsafe { collection::RefLockCollection::new_unchecked(&forks) };
let forks = forks.lock(key);
println!("{} is eating...", self.name);
thread::sleep(Duration::from_secs(1));
@@ -61,9 +61,13 @@ impl Philosopher {
}
fn main() {
- let handles = PHILOSOPHERS
+ let handles: Vec<_> = PHILOSOPHERS
.iter()
- .map(|philosopher| thread::spawn(move || philosopher.cycle()));
+ .map(|philosopher| thread::spawn(move || philosopher.cycle()))
+ // The `collect` is absolutely necessary, because we're using lazy
+ // iterators. If `collect` isn't used, then the thread won't spawn
+ // until we try to join on it.
+ .collect();
for handle in handles {
_ = handle.join();
diff --git a/examples/dining_philosophers_retry.rs b/examples/dining_philosophers_retry.rs
new file mode 100644
index 0000000..4302bc7
--- /dev/null
+++ b/examples/dining_philosophers_retry.rs
@@ -0,0 +1,75 @@
+use std::{thread, time::Duration};
+
+use happylock::{collection, Mutex, ThreadKey};
+
+static PHILOSOPHERS: [Philosopher; 5] = [
+ Philosopher {
+ name: "Socrates",
+ left: 0,
+ right: 1,
+ },
+ Philosopher {
+ name: "John Rawls",
+ left: 1,
+ right: 2,
+ },
+ Philosopher {
+ name: "Jeremy Bentham",
+ left: 2,
+ right: 3,
+ },
+ Philosopher {
+ name: "John Stuart Mill",
+ left: 3,
+ right: 4,
+ },
+ Philosopher {
+ name: "Judith Butler",
+ left: 4,
+ right: 0,
+ },
+];
+
+static FORKS: [Mutex<()>; 5] = [
+ Mutex::new(()),
+ Mutex::new(()),
+ Mutex::new(()),
+ Mutex::new(()),
+ Mutex::new(()),
+];
+
+struct Philosopher {
+ name: &'static str,
+ left: usize,
+ right: usize,
+}
+
+impl Philosopher {
+ fn cycle(&self) {
+ let key = ThreadKey::get().unwrap();
+ thread::sleep(Duration::from_secs(1));
+
+ // safety: no philosopher asks for the same fork twice
+ let forks = [&FORKS[self.left], &FORKS[self.right]];
+ let forks = unsafe { collection::RetryingLockCollection::new_unchecked(&forks) };
+ let forks = forks.lock(key);
+ println!("{} is eating...", self.name);
+ thread::sleep(Duration::from_secs(1));
+ println!("{} is done eating", self.name);
+ drop(forks);
+ }
+}
+
+fn main() {
+ let handles: Vec<_> = PHILOSOPHERS
+ .iter()
+ .map(|philosopher| thread::spawn(move || philosopher.cycle()))
+ // The `collect` is absolutely necessary, because we're using lazy
+ // iterators. If `collect` isn't used, then the thread won't spawn
+ // until we try to join on it.
+ .collect();
+
+ for handle in handles {
+ _ = handle.join();
+ }
+}
diff --git a/examples/double_mutex.rs b/examples/double_mutex.rs
index 621f81e..ea61f0d 100644
--- a/examples/double_mutex.rs
+++ b/examples/double_mutex.rs
@@ -1,6 +1,6 @@
use std::thread;
-use happylock::{LockCollection, Mutex, ThreadKey};
+use happylock::{collection::RefLockCollection, Mutex, ThreadKey};
const N: usize = 10;
@@ -11,7 +11,7 @@ fn main() {
for _ in 0..N {
let th = thread::spawn(move || {
let key = ThreadKey::get().unwrap();
- let lock = LockCollection::new_ref(&DATA);
+ let lock = RefLockCollection::new(&DATA);
let mut guard = lock.lock(key);
*guard.1 = (100 - *guard.0).to_string();
*guard.0 += 1;
@@ -24,8 +24,8 @@ fn main() {
}
let key = ThreadKey::get().unwrap();
- let data = LockCollection::new_ref(&DATA);
+ let data = RefLockCollection::new(&DATA);
let data = data.lock(key);
- println!("{}", *data.0);
- println!("{}", *data.1);
+ println!("{}", data.0);
+ println!("{}", data.1);
}
diff --git a/examples/fibonacci.rs b/examples/fibonacci.rs
new file mode 100644
index 0000000..d43b01c
--- /dev/null
+++ b/examples/fibonacci.rs
@@ -0,0 +1,29 @@
+use happylock::{LockCollection, Mutex, ThreadKey};
+use std::thread;
+
+const N: usize = 36;
+
+static DATA: [Mutex<i32>; 2] = [Mutex::new(0), Mutex::new(1)];
+
+fn main() {
+ for _ in 0..N {
+ thread::spawn(move || {
+ let key = ThreadKey::get().unwrap();
+
+ // a reference to a type that implements `OwnedLockable` will never
+ // contain duplicates, so no duplicate checking is needed.
+ let collection = LockCollection::new_ref(&DATA);
+ let mut guard = collection.lock(key);
+
+ let x = *guard[1];
+ *guard[1] += *guard[0];
+ *guard[0] = x;
+ });
+ }
+
+ let key = ThreadKey::get().unwrap();
+ let data = LockCollection::new_ref(&DATA);
+ let data = data.lock(key);
+ println!("{}", data[0]);
+ println!("{}", data[1]);
+}
diff --git a/examples/list.rs b/examples/list.rs
index 3b03f2d..a649eeb 100644
--- a/examples/list.rs
+++ b/examples/list.rs
@@ -1,6 +1,6 @@
use std::thread;
-use happylock::{LockCollection, Mutex, ThreadKey};
+use happylock::{collection::RefLockCollection, Mutex, ThreadKey};
const N: usize = 10;
@@ -37,7 +37,7 @@ fn main() {
data.push(&DATA[rand % 6]);
}
- let Some(lock) = LockCollection::try_new(data) else {
+ let Some(lock) = RefLockCollection::try_new(&data) else {
continue;
};
let mut guard = lock.lock(&mut key);
@@ -56,9 +56,9 @@ fn main() {
}
let key = ThreadKey::get().unwrap();
- let data = LockCollection::new_ref(&DATA);
+ let data = RefLockCollection::new(&DATA);
let data = data.lock(key);
for val in &*data {
- println!("{}", **val);
+ println!("{val}");
}
}