Skip to content

Commit

Permalink
Join threads in MULTITHREADED_COMPUTE example.
Browse files Browse the repository at this point in the history
Join all threads before returning from the test case, to ensure that
we don't return from `main` until all open `Device`s have been
dropped.

This avoids a race condition in glibc in which a thread calling
`dlclose` can unmap a shared library's code even while the main thread
is still running its finalization functions. (See #5084 for details.)
Joining all threads before returning from the test ensures that the
Vulkan loader has finished `dlclose`-ing the Vulkan validation layer
shared library before `main` returns.

Remove `skip` for this test on GL/llvmpipe. With this change, that has
not been observed to crash. Without it, the test crashes within ten
runs or so.

Fixes #5084.
Fixed #4285.
  • Loading branch information
jimblandy committed Jan 24, 2024
1 parent 8d64915 commit cd5004c
Showing 1 changed file with 21 additions and 17 deletions.
38 changes: 21 additions & 17 deletions examples/src/hello_compute/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ static MULTITHREADED_COMPUTE: GpuTestConfiguration = GpuTestConfiguration::new()
TestParameters::default()
.downlevel_flags(wgpu::DownlevelFlags::COMPUTE_SHADERS)
.limits(wgpu::Limits::downlevel_defaults())
.skip(FailureCase::adapter("V3D"))
// Segfaults on linux CI only https://github.com/gfx-rs/wgpu/issues/4285
.skip(FailureCase::backend_adapter(wgpu::Backends::GL, "llvmpipe")),
.skip(FailureCase::adapter("V3D")),
)
.run_sync(|ctx| {
use std::{sync::mpsc, sync::Arc, thread, time::Duration};
Expand All @@ -69,25 +67,31 @@ static MULTITHREADED_COMPUTE: GpuTestConfiguration = GpuTestConfiguration::new()
let thread_count = 8;

let (tx, rx) = mpsc::channel();
for _ in 0..thread_count {
let tx = tx.clone();
let ctx = Arc::clone(&ctx);
thread::spawn(move || {
let input = &[100, 100, 100];
pollster::block_on(assert_execute_gpu(
&ctx.device,
&ctx.queue,
input,
&[25, 25, 25],
));
tx.send(true).unwrap();
});
}
let workers: Vec<_> = (0..thread_count)
.map(move |_| {
let tx = tx.clone();
let ctx = Arc::clone(&ctx);
thread::spawn(move || {
let input = &[100, 100, 100];
pollster::block_on(assert_execute_gpu(
&ctx.device,
&ctx.queue,
input,
&[25, 25, 25],
));
tx.send(true).unwrap();
})
})
.collect();

for _ in 0..thread_count {
rx.recv_timeout(Duration::from_secs(10))
.expect("A thread never completed.");
}

for worker in workers {
worker.join().unwrap();
}
});

async fn assert_execute_gpu(
Expand Down

0 comments on commit cd5004c

Please sign in to comment.