@@ -116,6 +116,7 @@ static bool waitForStatusRecordUnlockIfNotSelfLocked(AsyncTask *task,
116
116
// withStatusRecordLock so that lock record contents are visible due to
117
117
// load-through HW address dependency
118
118
status = task->_private ()._status ().load (SWIFT_MEMORY_ORDER_CONSUME);
119
+ _swift_tsan_consume (task);
119
120
120
121
if (!status.isStatusRecordLocked ())
121
122
return nullptr ;
@@ -134,6 +135,7 @@ static bool waitForStatusRecordUnlockIfNotSelfLocked(AsyncTask *task,
134
135
135
136
// Reload the status before trying to relock
136
137
status = task->_private ()._status ().load (SWIFT_MEMORY_ORDER_CONSUME);
138
+ _swift_tsan_consume (task);
137
139
if (!status.isStatusRecordLocked ())
138
140
return false ;
139
141
}
@@ -159,6 +161,7 @@ static void waitForStatusRecordUnlock(AsyncTask *task,
159
161
// withStatusRecordLock so that lock record contents are visible due to
160
162
// load-through HW address dependency
161
163
status = task->_private ()._status ().load (SWIFT_MEMORY_ORDER_CONSUME);
164
+ _swift_tsan_consume (task);
162
165
if (!status.isStatusRecordLocked ())
163
166
return nullptr ;
164
167
@@ -175,6 +178,7 @@ static void waitForStatusRecordUnlock(AsyncTask *task,
175
178
176
179
// Reload the status before trying to relock.
177
180
status = task->_private ()._status ().load (SWIFT_MEMORY_ORDER_CONSUME);
181
+ _swift_tsan_consume (task);
178
182
if (!status.isStatusRecordLocked ())
179
183
return ;
180
184
}
@@ -215,13 +219,17 @@ static bool withStatusRecordLock(AsyncTask *task, ActiveTaskStatus status,
215
219
oldRecord = status.getInnermostRecord ();
216
220
lockingRecord = worker.createQueue (oldRecord);
217
221
218
- // Publish the lock record with an acquire so that all lock operations are
219
- // bounded.
222
+ // Publish the lock record
223
+ // * We need an acquire to pair with release of someone else who might have
224
+ // unlocked
225
+ // * We need a store release to publish the lock record contents
220
226
ActiveTaskStatus newStatus = status.withLockingRecord (lockingRecord);
221
227
if (task->_private ()._status ().compare_exchange_weak (status, newStatus,
222
- /* success*/ std::memory_order_acquire ,
228
+ /* success*/ std::memory_order_acq_rel ,
223
229
/* failure*/ std::memory_order_relaxed)) {
224
230
_swift_tsan_acquire (task);
231
+ _swift_tsan_release (task);
232
+
225
233
status = newStatus;
226
234
227
235
status.traceStatusChanged (task);
@@ -617,6 +625,7 @@ static void swift_task_cancelImpl(AsyncTask *task) {
617
625
if (task->_private ()._status ().compare_exchange_weak (oldStatus, newStatus,
618
626
/* success*/ SWIFT_MEMORY_ORDER_CONSUME,
619
627
/* failure*/ std::memory_order_relaxed)) {
628
+ _swift_tsan_consume (task);
620
629
break ;
621
630
}
622
631
}
@@ -723,6 +732,7 @@ static swift_task_escalateImpl(AsyncTask *task, JobPriority newPriority) {
723
732
if (task->_private ()._status ().compare_exchange_weak (oldStatus, newStatus,
724
733
/* success */ SWIFT_MEMORY_ORDER_CONSUME,
725
734
/* failure */ std::memory_order_relaxed)) {
735
+ _swift_tsan_consume (task);
726
736
break ;
727
737
}
728
738
}
0 commit comments