diff options
Diffstat (limited to 'openmp/libomptarget/DeviceRTL/src/Parallelism.cpp')
-rw-r--r-- | openmp/libomptarget/DeviceRTL/src/Parallelism.cpp | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/openmp/libomptarget/DeviceRTL/src/Parallelism.cpp b/openmp/libomptarget/DeviceRTL/src/Parallelism.cpp index d2fee1123630..d32dd7e4f998 100644 --- a/openmp/libomptarget/DeviceRTL/src/Parallelism.cpp +++ b/openmp/libomptarget/DeviceRTL/src/Parallelism.cpp @@ -113,7 +113,7 @@ void __kmpc_parallel_51(IdentTy *ident, int32_t, int32_t if_expr, if (mapping::isSPMDMode()) { // Avoid the race between the read of the `icv::Level` above and the write // below by synchronizing all threads here. - synchronize::threadsAligned(); + synchronize::threadsAligned(atomic::seq_cst); { // Note that the order here is important. `icv::Level` has to be updated // last or the other updates will cause a thread specific state to be @@ -128,28 +128,36 @@ void __kmpc_parallel_51(IdentTy *ident, int32_t, int32_t if_expr, // Synchronize all threads after the main thread (TId == 0) set up the // team state properly. - synchronize::threadsAligned(); + synchronize::threadsAligned(atomic::acq_rel); state::ParallelTeamSize.assert_eq(NumThreads, ident, /* ForceTeamState */ true); icv::ActiveLevel.assert_eq(1u, ident, /* ForceTeamState */ true); icv::Level.assert_eq(1u, ident, /* ForceTeamState */ true); + // Ensure we synchronize before we run user code to avoid invalidating the + // assumptions above. + synchronize::threadsAligned(atomic::relaxed); + if (TId < NumThreads) invokeMicrotask(TId, 0, fn, args, nargs); // Synchronize all threads at the end of a parallel region. - synchronize::threadsAligned(); + synchronize::threadsAligned(atomic::seq_cst); } // Synchronize all threads to make sure every thread exits the scope above; // otherwise the following assertions and the assumption in // __kmpc_target_deinit may not hold. - synchronize::threadsAligned(); + synchronize::threadsAligned(atomic::acq_rel); state::ParallelTeamSize.assert_eq(1u, ident, /* ForceTeamState */ true); icv::ActiveLevel.assert_eq(0u, ident, /* ForceTeamState */ true); icv::Level.assert_eq(0u, ident, /* ForceTeamState */ true); + + // Ensure we synchronize to create an aligned region around the assumptions. + synchronize::threadsAligned(atomic::relaxed); + return; } @@ -243,9 +251,9 @@ void __kmpc_parallel_51(IdentTy *ident, int32_t, int32_t if_expr, /* ForceTeamState */ true); // Master signals work to activate workers. - synchronize::threads(); + synchronize::threads(atomic::seq_cst); // Master waits for workers to signal. - synchronize::threads(); + synchronize::threads(atomic::seq_cst); } if (nargs) |