diff --git a/leetcode/1116.print-zero-even-odd/src/with_condvar.rs b/leetcode/1116.print-zero-even-odd/src/with_condvar.rs index a8bdc701..99b25253 100644 --- a/leetcode/1116.print-zero-even-odd/src/with_condvar.rs +++ b/leetcode/1116.print-zero-even-odd/src/with_condvar.rs @@ -10,14 +10,8 @@ use std::thread; struct ZeroEvenOdd { n: i32, - zero_mutex: Mutex, - zero_cvar: Condvar, - - even_mutex: Mutex, - even_cvar: Condvar, - - odd_mutex: Mutex, - odd_cvar: Condvar, + mutex: Mutex, + cvar: Condvar, } fn print_number(_prefix: &str, x: i32) { @@ -27,112 +21,55 @@ fn print_number(_prefix: &str, x: i32) { impl ZeroEvenOdd { pub fn new(n: i32) -> Self { Self { - n, - - zero_mutex: Mutex::new(true), - zero_cvar: Condvar::new(), - - even_mutex: Mutex::new(0), - even_cvar: Condvar::new(), + n: 2 * n, - odd_mutex: Mutex::new(0), - odd_cvar: Condvar::new(), + mutex: Mutex::new(1), + cvar: Condvar::new(), } } pub fn zero(&self) { - for i in 0..=self.n { - { - let mut zero_mutex = self.zero_mutex.lock().unwrap(); - while !*zero_mutex { - zero_mutex = self.zero_cvar.wait(zero_mutex).unwrap(); - } - *zero_mutex = false; + loop { + let mut mutex = self.mutex.lock().unwrap(); + while *mutex <= self.n && *mutex % 2 == 0 { + mutex = self.cvar.wait(mutex).unwrap(); } - if i == self.n { - break; + if *mutex > self.n { + return; } - print_number("zero", 0); - - let next_num = i + 1; - if next_num % 2 == 0 { - let mut num_mutex = self.even_mutex.lock().unwrap(); - *num_mutex = next_num; - self.even_cvar.notify_one(); - } else { - let mut num_mutex = self.odd_mutex.lock().unwrap(); - *num_mutex = next_num; - self.odd_cvar.notify_one(); - } - } - - { - let mut num_mutex = self.even_mutex.lock().unwrap(); - *num_mutex = -1; - self.even_cvar.notify_one(); - } - { - let mut num_mutex = self.odd_mutex.lock().unwrap(); - *num_mutex = -1; - self.odd_cvar.notify_one(); + *mutex += 1; + self.cvar.notify_all(); } } pub fn even(&self) { loop { - let even_num; - { - let mut num_mutex = self.even_mutex.lock().unwrap(); - loop { - if *num_mutex == -1 { - return; - } - if *num_mutex != 0 { - break; - } - num_mutex = self.even_cvar.wait(num_mutex).unwrap(); - } - - even_num = *num_mutex; - *num_mutex = 0; + let mut mutex = self.mutex.lock().unwrap(); + while *mutex <= self.n && (*mutex % 2 != 0 || *mutex % 4 != 0) { + mutex = self.cvar.wait(mutex).unwrap(); } - - print_number("even", even_num); - { - let mut zero_mutex = self.zero_mutex.lock().unwrap(); - *zero_mutex = true; - self.zero_cvar.notify_one(); + if *mutex > self.n { + return; } + print_number("even", *mutex / 2); + *mutex += 1; + self.cvar.notify_all(); } } pub fn odd(&self) { loop { - let odd_num; - { - let mut num_mutex = self.odd_mutex.lock().unwrap(); - loop { - if *num_mutex == -1 { - return; - } - if *num_mutex != 0 { - break; - } - num_mutex = self.odd_cvar.wait(num_mutex).unwrap(); - } - - odd_num = *num_mutex; - *num_mutex = 0; + let mut mutex = self.mutex.lock().unwrap(); + while *mutex <= self.n && (*mutex % 2 != 0 || *mutex % 4 == 0) { + mutex = self.cvar.wait(mutex).unwrap(); } - - print_number("odd", odd_num); - - { - let mut zero_mutex = self.zero_mutex.lock().unwrap(); - *zero_mutex = true; - self.zero_cvar.notify_one(); + if *mutex > self.n { + return; } + print_number("odd", *mutex / 2); + *mutex += 1; + self.cvar.notify_all(); } } }