Skip to content

Commit

Permalink
Join threads in MULTITHREADED_COMPUTE example. (gfx-rs#5129)
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 gfx-rs#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 gfx-rs#5084.
Fixed gfx-rs#4285.
  • Loading branch information
jimblandy committed Jan 24, 2024
1 parent 8d64915 commit 6440af0
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 17 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ Bottom level categories:

- In Surface::configure and Surface::present, fix the current GL context not being unset when releasing the lock that guards access to making the context current. This was causing other threads to panic when trying to make the context current. By @Imberflur in [#5087](https://github.com/gfx-rs/wgpu/pull/5087).

#### Tests

- Fix intermittent crashes on Linux in the `multithreaded_compute` test. By @jimblandy in [#5129](https://github.com/gfx-rs/wgpu/pull/5129).

## v0.19.0 (2024-01-17)

This release includes:
Expand Down
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 6440af0

Please sign in to comment.