Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify thread blocking tests #4059

Merged
merged 1 commit into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions tests/fail-dep/libc/eventfd_block_read_twice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ fn main() {
let fd = unsafe { libc::eventfd(0, flags) };

let thread1 = thread::spawn(move || {
thread::park();
let mut buf: [u8; 8] = [0; 8];
// This read will block initially.
let res: i64 = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), 8).try_into().unwrap() };
Expand All @@ -33,7 +32,6 @@ fn main() {
});

let thread2 = thread::spawn(move || {
thread::park();
let mut buf: [u8; 8] = [0; 8];
// This read will block initially, then get unblocked by thread3, then get blocked again
// because the `read` in thread1 executes first and set the counter to 0 again.
Expand All @@ -45,7 +43,6 @@ fn main() {
});

let thread3 = thread::spawn(move || {
thread::park();
let sized_8_data = 1_u64.to_ne_bytes();
// Write 1 to the counter, so both thread1 and thread2 will unblock.
let res: i64 = unsafe {
Expand All @@ -55,10 +52,6 @@ fn main() {
assert_eq!(res, 8);
});

thread1.thread().unpark();
thread2.thread().unpark();
thread3.thread().unpark();

thread1.join().unwrap();
thread2.join().unwrap();
thread3.join().unwrap();
Expand Down
7 changes: 0 additions & 7 deletions tests/fail-dep/libc/eventfd_block_write_twice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ fn main() {
assert_eq!(res, 8);

let thread1 = thread::spawn(move || {
thread::park();
let sized_8_data = (u64::MAX - 1).to_ne_bytes();
let res: i64 = unsafe {
libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap()
Expand All @@ -38,7 +37,6 @@ fn main() {
});

let thread2 = thread::spawn(move || {
thread::park();
let sized_8_data = (u64::MAX - 1).to_ne_bytes();
// Write u64::MAX - 1, so the all subsequent write will block.
let res: i64 = unsafe {
Expand All @@ -52,7 +50,6 @@ fn main() {
});

let thread3 = thread::spawn(move || {
thread::park();
let mut buf: [u8; 8] = [0; 8];
// This will unblock both `write` in thread1 and thread2.
let res: i64 = unsafe { libc::read(fd, buf.as_mut_ptr().cast(), 8).try_into().unwrap() };
Expand All @@ -61,10 +58,6 @@ fn main() {
assert_eq!(counter, (u64::MAX - 1));
});

thread1.thread().unpark();
thread2.thread().unpark();
thread3.thread().unpark();

thread1.join().unwrap();
thread2.join().unwrap();
thread3.join().unwrap();
Expand Down
32 changes: 11 additions & 21 deletions tests/fail-dep/libc/libc_epoll_block_two_thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
//@error-in-other-file: deadlock

use std::convert::TryInto;
use std::thread;
use std::thread::spawn;

// Using `as` cast since `EPOLLET` wraps around
Expand Down Expand Up @@ -41,10 +40,10 @@ fn check_epoll_wait<const N: usize>(

// Test if only one thread is unblocked if multiple threads blocked on same epfd.
// Expected execution:
// 1. Thread 2 blocks.
// 2. Thread 3 blocks.
// 3. Thread 1 unblocks thread 3.
// 4. Thread 2 deadlocks.
// 1. Thread 1 blocks.
// 2. Thread 2 blocks.
// 3. Thread 3 unblocks thread 2.
// 4. Thread 1 deadlocks.
fn main() {
// Create an epoll instance.
let epfd = unsafe { libc::epoll_create1(0) };
Expand All @@ -65,30 +64,21 @@ fn main() {
let expected_value = fds[0] as u64;
check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], 0);

let thread1 = spawn(move || {
thread::park();
let data = "abcde".as_bytes().as_ptr();
let res = unsafe { libc::write(fds[1], data as *const libc::c_void, 5) };
assert_eq!(res, 5);
});

let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
let expected_value = fds[0] as u64;
let thread2 = spawn(move || {
thread::park();
let thread1 = spawn(move || {
check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], -1);
//~^ERROR: deadlocked
});
let thread3 = spawn(move || {
thread::park();
let thread2 = spawn(move || {
check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], -1);
});

thread2.thread().unpark();
thread::yield_now();
thread3.thread().unpark();
thread::yield_now();
thread1.thread().unpark();
let thread3 = spawn(move || {
let data = "abcde".as_bytes().as_ptr();
let res = unsafe { libc::write(fds[1], data as *const libc::c_void, 5) };
assert_eq!(res, 5);
});

thread1.join().unwrap();
thread2.join().unwrap();
Expand Down
14 changes: 7 additions & 7 deletions tests/fail-dep/libc/libc_epoll_block_two_thread.stderr
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
error: deadlock: the evaluated program deadlocked
|
= note: the evaluated program deadlocked
= note: (no span available)
= note: BACKTRACE on thread `unnamed-ID`:

error: deadlock: the evaluated program deadlocked
--> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
|
Expand All @@ -11,15 +17,9 @@ LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
note: inside `main`
--> tests/fail-dep/libc/libc_epoll_block_two_thread.rs:LL:CC
|
LL | thread2.join().unwrap();
LL | thread1.join().unwrap();
| ^^^^^^^^^^^^^^

error: deadlock: the evaluated program deadlocked
|
= note: the evaluated program deadlocked
= note: (no span available)
= note: BACKTRACE on thread `unnamed-ID`:

error: deadlock: the evaluated program deadlocked
--> tests/fail-dep/libc/libc_epoll_block_two_thread.rs:LL:CC
|
Expand Down
7 changes: 0 additions & 7 deletions tests/pass-dep/libc/libc-eventfd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,6 @@ fn test_two_threads_blocked_on_eventfd() {
assert_eq!(res, 8);

let thread1 = thread::spawn(move || {
thread::park();
let sized_8_data = 1_u64.to_ne_bytes();
let res: i64 = unsafe {
libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap()
Expand All @@ -207,7 +206,6 @@ fn test_two_threads_blocked_on_eventfd() {
});

let thread2 = thread::spawn(move || {
thread::park();
let sized_8_data = 1_u64.to_ne_bytes();
let res: i64 = unsafe {
libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap()
Expand All @@ -217,7 +215,6 @@ fn test_two_threads_blocked_on_eventfd() {
});

let thread3 = thread::spawn(move || {
thread::park();
let mut buf: [u8; 8] = [0; 8];
// This will unblock previously blocked eventfd read.
let res = read_bytes(fd, &mut buf);
Expand All @@ -227,10 +224,6 @@ fn test_two_threads_blocked_on_eventfd() {
assert_eq!(counter, (u64::MAX - 1));
});

thread1.thread().unpark();
thread2.thread().unpark();
thread3.thread().unpark();

thread1.join().unwrap();
thread2.join().unwrap();
thread3.join().unwrap();
Expand Down