Skip to content

Commit

Permalink
Merge pull request #4059 from tiif/fixtest
Browse files Browse the repository at this point in the history
Simplify thread blocking tests
  • Loading branch information
oli-obk authored Nov 26, 2024
2 parents 401abf7 + 27ff713 commit 7b10fd0
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 49 deletions.
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

0 comments on commit 7b10fd0

Please sign in to comment.