Skip to content

Commit cc440f2

Browse files
committed
Fix deadlock on Linux due to try_lock in the loop
Signed-off-by: Dmitry Vodopyanov <[email protected]>
1 parent 7c0eb15 commit cc440f2

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

sycl/source/detail/scheduler/scheduler.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,13 @@ EventImplPtr Scheduler::addCG(std::unique_ptr<detail::CG> CommandGroup,
6767
const bool IsKernel = CommandGroup->getType() == CG::KERNEL;
6868
{
6969
std::unique_lock<std::shared_timed_mutex> Lock(MGraphLock, std::defer_lock);
70+
#ifdef _WIN32
7071
while (!Lock.owns_lock()) {
7172
Lock.try_lock();
7273
}
74+
#else
75+
Lock.lock();
76+
#endif // _WIN32
7377

7478
switch (CommandGroup->getType()) {
7579
case CG::UPDATE_HOST:
@@ -95,9 +99,13 @@ EventImplPtr Scheduler::addCG(std::unique_ptr<detail::CG> CommandGroup,
9599

96100
EventImplPtr Scheduler::addCopyBack(Requirement *Req) {
97101
std::unique_lock<std::shared_timed_mutex> Lock(MGraphLock, std::defer_lock);
102+
#ifdef _WIN32
98103
while (!Lock.owns_lock()) {
99104
Lock.try_lock();
100105
}
106+
#else
107+
Lock.lock();
108+
#endif // _WIN32
101109
Command *NewCmd = MGraphBuilder.addCopyBack(Req);
102110
// Command was not creted because there were no operations with
103111
// buffer.
@@ -154,9 +162,13 @@ void Scheduler::cleanupFinishedCommands(EventImplPtr FinishedEvent) {
154162

155163
void Scheduler::removeMemoryObject(detail::SYCLMemObjI *MemObj) {
156164
std::unique_lock<std::shared_timed_mutex> Lock(MGraphLock, std::defer_lock);
165+
#ifdef _WIN32
157166
while (!Lock.owns_lock()) {
158167
Lock.try_lock();
159168
}
169+
#else
170+
Lock.lock();
171+
#endif // _WIN32
160172

161173
MemObjRecord *Record = MGraphBuilder.getMemObjRecord(MemObj);
162174
if (!Record)
@@ -170,14 +182,20 @@ void Scheduler::removeMemoryObject(detail::SYCLMemObjI *MemObj) {
170182

171183
EventImplPtr Scheduler::addHostAccessor(Requirement *Req,
172184
const bool destructor) {
185+
std::unique_lock<std::shared_timed_mutex> Lock(MGraphLock, std::defer_lock);
173186
// Avoiding deadlock situation for MSVC. std::shared_timed_mutex specification
174187
// does not specify a priority for shared and exclusive accesses. It will be a
175188
// deadlock in MSVC's std::shared_timed_mutex implementation, if exclusive
176189
// access occurs after shared access.
177-
std::unique_lock<std::shared_timed_mutex> Lock(MGraphLock, std::defer_lock);
190+
// TODO: after switching to C++17, change std::shared_timed_mutex to
191+
// std::shared_mutex and use std::lock_guard here both for Windows and Linux.
192+
#ifdef _WIN32
178193
while (!Lock.owns_lock()) {
179194
Lock.try_lock();
180195
}
196+
#else
197+
Lock.lock();
198+
#endif // _WIN32
181199

182200
Command *NewCmd = MGraphBuilder.addHostAccessor(Req, destructor);
183201

@@ -191,8 +209,8 @@ EventImplPtr Scheduler::addHostAccessor(Requirement *Req,
191209
}
192210

193211
void Scheduler::releaseHostAccessor(Requirement *Req) {
194-
std::shared_lock<std::shared_timed_mutex> Lock(MGraphLock);
195212
Req->MBlockedCmd->MEnqueueStatus = EnqueueResultT::SyclEnqueueReady;
213+
std::shared_lock<std::shared_timed_mutex> Lock(MGraphLock);
196214
MemObjRecord *Record = Req->MSYCLMemObj->MRecord.get();
197215
auto EnqueueLeaves = [](CircularBuffer<Command *> &Leaves) {
198216
for (Command *Cmd : Leaves) {

0 commit comments

Comments
 (0)