diff options
| author | Botahamec <botahamec@outlook.com> | 2024-05-23 19:54:38 -0400 |
|---|---|---|
| committer | Botahamec <botahamec@outlook.com> | 2024-05-23 19:54:38 -0400 |
| commit | 046c93cbea3236b7adf9e473d299345ee985cbb2 (patch) | |
| tree | 47cb8d1d1add67c0a8a5f3b86edf89ff4c03c4bf /examples | |
| parent | 698dd9dac7f0ca02ded9b3a56b45ac71a7dbbb04 (diff) | |
Another dining philosophers test
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/dining_philosophers.rs | 4 | ||||
| -rw-r--r-- | examples/dining_philosophers_retry.rs | 75 |
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(); + } +} |
