diff --git a/openmp/libomptarget/DeviceRTL/include/Mapping.h b/openmp/libomptarget/DeviceRTL/include/Mapping.h --- a/openmp/libomptarget/DeviceRTL/include/Mapping.h +++ b/openmp/libomptarget/DeviceRTL/include/Mapping.h @@ -37,6 +37,11 @@ bool isMainThreadInGenericMode(); bool isMainThreadInGenericMode(bool IsSPMD); +/// Return true if this thread should be used for single threaded +/// initialization tasks. We pick a special thread to ensure there are no +/// races between the initialization and the first read of initialized state. +bool isInitializationThread(bool IsSPMD); + /// Return true if the executing thread has the lowest Id of the active threads /// in the warp. bool isLeaderInWarp(); diff --git a/openmp/libomptarget/DeviceRTL/src/Mapping.cpp b/openmp/libomptarget/DeviceRTL/src/Mapping.cpp --- a/openmp/libomptarget/DeviceRTL/src/Mapping.cpp +++ b/openmp/libomptarget/DeviceRTL/src/Mapping.cpp @@ -178,6 +178,12 @@ return mapping::isMainThreadInGenericMode(mapping::isSPMDMode()); } +bool mapping::isInitializationThread(bool IsSPMD) { + if (IsSPMD) + return mapping::getThreadIdInBlock() == 0; + return mapping::isMainThreadInGenericMode(IsSPMD); +} + bool mapping::isLeaderInWarp() { __kmpc_impl_lanemask_t Active = mapping::activemask(); __kmpc_impl_lanemask_t LaneMaskLT = mapping::lanemaskLT(); @@ -220,7 +226,7 @@ static int SHARED(IsSPMDMode); void mapping::init(bool IsSPMD) { - if (!mapping::getThreadIdInBlock()) + if (mapping::isInitializationThread(IsSPMD)) IsSPMDMode = IsSPMD; } diff --git a/openmp/libomptarget/DeviceRTL/src/State.cpp b/openmp/libomptarget/DeviceRTL/src/State.cpp --- a/openmp/libomptarget/DeviceRTL/src/State.cpp +++ b/openmp/libomptarget/DeviceRTL/src/State.cpp @@ -366,7 +366,7 @@ void state::init(bool IsSPMD) { SharedMemorySmartStack.init(IsSPMD); - if (!mapping::getThreadIdInBlock()) + if (mapping::isInitializationThread(IsSPMD)) TeamState.init(IsSPMD); ThreadStates[mapping::getThreadIdInBlock()] = nullptr;