@@ -67,13 +67,7 @@ EventImplPtr Scheduler::addCG(std::unique_ptr<detail::CG> CommandGroup,
67
67
const bool IsKernel = CommandGroup->getType () == CG::KERNEL;
68
68
{
69
69
std::unique_lock<std::shared_timed_mutex> Lock (MGraphLock, std::defer_lock);
70
- #ifdef _WIN32
71
- while (!Lock.owns_lock ()) {
72
- Lock.try_lock ();
73
- }
74
- #else
75
- Lock.lock ();
76
- #endif // _WIN32
70
+ lockSharedTimedMutex (Lock);
77
71
78
72
switch (CommandGroup->getType ()) {
79
73
case CG::UPDATE_HOST:
@@ -99,13 +93,7 @@ EventImplPtr Scheduler::addCG(std::unique_ptr<detail::CG> CommandGroup,
99
93
100
94
EventImplPtr Scheduler::addCopyBack (Requirement *Req) {
101
95
std::unique_lock<std::shared_timed_mutex> Lock (MGraphLock, std::defer_lock);
102
- #ifdef _WIN32
103
- while (!Lock.owns_lock ()) {
104
- Lock.try_lock ();
105
- }
106
- #else
107
- Lock.lock ();
108
- #endif // _WIN32
96
+ lockSharedTimedMutex (Lock);
109
97
Command *NewCmd = MGraphBuilder.addCopyBack (Req);
110
98
// Command was not creted because there were no operations with
111
99
// buffer.
@@ -162,13 +150,7 @@ void Scheduler::cleanupFinishedCommands(EventImplPtr FinishedEvent) {
162
150
163
151
void Scheduler::removeMemoryObject (detail::SYCLMemObjI *MemObj) {
164
152
std::unique_lock<std::shared_timed_mutex> Lock (MGraphLock, std::defer_lock);
165
- #ifdef _WIN32
166
- while (!Lock.owns_lock ()) {
167
- Lock.try_lock ();
168
- }
169
- #else
170
- Lock.lock ();
171
- #endif // _WIN32
153
+ lockSharedTimedMutex (Lock);
172
154
173
155
MemObjRecord *Record = MGraphBuilder.getMemObjRecord (MemObj);
174
156
if (!Record)
@@ -183,19 +165,7 @@ void Scheduler::removeMemoryObject(detail::SYCLMemObjI *MemObj) {
183
165
EventImplPtr Scheduler::addHostAccessor (Requirement *Req,
184
166
const bool destructor) {
185
167
std::unique_lock<std::shared_timed_mutex> Lock (MGraphLock, std::defer_lock);
186
- // Avoiding deadlock situation for MSVC. std::shared_timed_mutex specification
187
- // does not specify a priority for shared and exclusive accesses. It will be a
188
- // deadlock in MSVC's std::shared_timed_mutex implementation, if exclusive
189
- // access occurs after shared access.
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
193
- while (!Lock.owns_lock ()) {
194
- Lock.try_lock ();
195
- }
196
- #else
197
- Lock.lock ();
198
- #endif // _WIN32
168
+ lockSharedTimedMutex (Lock);
199
169
200
170
Command *NewCmd = MGraphBuilder.addHostAccessor (Req, destructor);
201
171
@@ -231,6 +201,25 @@ Scheduler::Scheduler() {
231
201
QueueOrder::Ordered, /* PropList=*/ {}));
232
202
}
233
203
204
+ void Scheduler::lockSharedTimedMutex (
205
+ std::unique_lock<std::shared_timed_mutex> &Lock) {
206
+ #ifdef _WIN32
207
+ // Avoiding deadlock situation for MSVC. std::shared_timed_mutex specification
208
+ // does not specify a priority for shared and exclusive accesses. It will be a
209
+ // deadlock in MSVC's std::shared_timed_mutex implementation, if exclusive
210
+ // access occurs after shared access.
211
+ // TODO: after switching to C++17, change std::shared_timed_mutex to
212
+ // std::shared_mutex and use std::lock_guard here both for Windows and Linux.
213
+ while (!Lock.owns_lock ()) {
214
+ Lock.try_lock ();
215
+ }
216
+ #else
217
+ // It is a deadlock on UNIX in implementation of lock and lock_shared, if
218
+ // try_lock in the loop above will be executed, so using a single lock here
219
+ Lock.lock ();
220
+ #endif // _WIN32
221
+ }
222
+
234
223
} // namespace detail
235
224
} // namespace sycl
236
225
} // __SYCL_INLINE_NAMESPACE(cl)
0 commit comments