summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBotahamec <botahamec@outlook.com>2024-05-23 19:54:38 -0400
committerBotahamec <botahamec@outlook.com>2024-05-23 19:54:38 -0400
commit046c93cbea3236b7adf9e473d299345ee985cbb2 (patch)
tree47cb8d1d1add67c0a8a5f3b86edf89ff4c03c4bf
parent698dd9dac7f0ca02ded9b3a56b45ac71a7dbbb04 (diff)
Another dining philosophers test
-rw-r--r--examples/dining_philosophers.rs4
-rw-r--r--examples/dining_philosophers_retry.rs75
2 files changed, 77 insertions, 2 deletions
diff --git a/examples/dining_philosophers.rs b/examples/dining_philosophers.rs
index 1340564..dc4dd51 100644
--- a/examples/dining_philosophers.rs
+++ b/examples/dining_philosophers.rs
@@ -1,6 +1,6 @@
use std::{thread, time::Duration};
-use happylock::{collection::RefLockCollection, Mutex, ThreadKey};
+use happylock::{collection, Mutex, ThreadKey};
static PHILOSOPHERS: [Philosopher; 5] = [
Philosopher {
@@ -51,7 +51,7 @@ impl Philosopher {
// safety: no philosopher asks for the same fork twice
let forks = [&FORKS[self.left], &FORKS[self.right]];
- let forks = unsafe { RefLockCollection::new_unchecked(&forks) };
+ let forks = unsafe { collection::RefLockCollection::new_unchecked(&forks) };
let forks = forks.lock(key);
println!("{} is eating...", self.name);
thread::sleep(Duration::from_secs(1));
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();
+ }
+}