Created
May 23, 2025 21:21
-
-
Save PeterCxy/b1307059fc0c06115e08f59f9664f407 to your computer and use it in GitHub Desktop.
parking_lot RwLock lockup reproduction
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use parking_lot::RwLock; | |
use std::ops::Deref; | |
use std::sync::Arc; | |
use std::time::Duration; | |
#[tokio::main(flavor = "multi_thread", worker_threads = 64)] | |
async fn main() { | |
let lock = Arc::new(RwLock::new(())); | |
//let mut addr = lock.deref() as *const RwLock<_> as *const usize; | |
//println!("lock addr is {addr:p}"); | |
for _ in 0..1000 { | |
let lock = lock.clone(); | |
tokio::task::spawn(async move { stress_lock(lock).await }); | |
} | |
//let addr = addr as usize; | |
//std::thread::spawn(move || print_lock(addr)); | |
tokio::time::sleep(Duration::from_secs(180)).await; | |
} | |
fn print_lock(addr: usize) { | |
let addr = addr as *const usize; | |
loop { | |
let val = unsafe { std::ptr::read_volatile(addr) }; | |
println!("lock: {:x}", val); | |
std::thread::sleep(Duration::from_secs(1)); | |
} | |
} | |
async fn stress_lock(lock: Arc<RwLock<()>>) { | |
loop { | |
let r: u32 = rand::random_range(..100); | |
if r == 0 { | |
#[cfg(feature = "write_timeout")] | |
write_timeout(&lock).await; | |
#[cfg(not(feature = "write_timeout"))] | |
write(&lock).await; | |
} else { | |
read(&lock).await | |
} | |
} | |
} | |
async fn read(lock: &Arc<RwLock<()>>) { | |
let guard = lock.read(); | |
let r: u64 = rand::random_range(100..2000); | |
std::thread::sleep(Duration::from_micros(r)); | |
drop(guard); | |
} | |
#[cfg(not(feature = "write_timeout"))] | |
async fn write(lock: &Arc<RwLock<()>>) { | |
let guard = lock.write(); | |
let r: u64 = rand::random_range(100..1000); | |
std::thread::sleep(Duration::from_micros(r)); | |
drop(guard); | |
} | |
#[cfg(feature = "write_timeout")] | |
async fn write_timeout(lock: &Arc<parking_lot::RwLock<()>>) { | |
let guard = loop { | |
if let Some(guard) = lock.try_write_for(Duration::from_micros(100)) { | |
break guard; | |
} | |
std::thread::sleep(Duration::from_micros(100)); | |
}; | |
let r: u64 = rand::random_range(100..1000); | |
std::thread::sleep(Duration::from_micros(r)); | |
drop(guard); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use parking_lot::RwLock; | |
use std::ops::Deref; | |
use std::sync::Arc; | |
use std::time::Duration; | |
fn main() { | |
let lock = Arc::new(RwLock::new(())); | |
for _ in 0..64 { | |
let lock = lock.clone(); | |
std::thread::spawn(move || stress_lock(lock)); | |
} | |
//let addr = lock.deref() as *const RwLock<_> as *const usize as usize; | |
//let t = std::thread::spawn(move || print_lock(addr)); | |
t.join().ok(); | |
} | |
//fn print_lock(addr: usize) { | |
// let addr = addr as *const usize; | |
// loop { | |
// let val = unsafe { std::ptr::read_volatile(addr) }; | |
// println!("lock: {:x}", val); | |
// std::thread::sleep(Duration::from_secs(1)); | |
// } | |
//} | |
fn stress_lock(lock: Arc<RwLock<()>>) { | |
loop { | |
let r: u32 = rand::random_range(..100); | |
if r == 0 { | |
#[cfg(feature = "write_timeout")] | |
write_timeout(&lock); | |
#[cfg(not(feature = "write_timeout"))] | |
write(&lock); | |
} else { | |
read(&lock); | |
} | |
} | |
} | |
fn read(lock: &Arc<RwLock<()>>) { | |
let guard = lock.read(); | |
let r: u64 = rand::random_range(100..2000); | |
std::thread::sleep(Duration::from_micros(r)); | |
drop(guard); | |
} | |
#[cfg(not(feature = "write_timeout"))] | |
fn write(lock: &Arc<RwLock<()>>) { | |
let guard = lock.write(); | |
let r: u64 = rand::random_range(100..1000); | |
std::thread::sleep(Duration::from_micros(r)); | |
drop(guard); | |
} | |
#[cfg(feature = "write_timeout")] | |
fn write_timeout(lock: &Arc<parking_lot::RwLock<()>>) { | |
let guard = loop { | |
if let Some(guard) = lock.try_write_for(Duration::from_micros(100)) { | |
break guard; | |
} | |
std::thread::sleep(Duration::from_micros(100)); | |
}; | |
let r: u64 = rand::random_range(100..1000); | |
std::thread::sleep(Duration::from_micros(r)); | |
drop(guard); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment