Skip to content

Commit ce3da79

Browse files
kavonrjmccall
andcommitted
completeFuture should have acquire-release for the exchange
When a completed task updates the queue head to announce that it's been completed, it only did an acquire exchange. By also having it also do a release, we will ensure that prior writes done by the completed task, before the task is marked completed, will be correctly ordered as happening before any subsequent reads by tasks waiting on that completion status. Co-authored-by: John McCall <[email protected]>
1 parent ac10f2a commit ce3da79

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

stdlib/public/Concurrency/Task.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ FutureFragment::Status AsyncTask::waitFuture(AsyncTask *waitingTask,
114114
assert(isFuture());
115115
auto fragment = futureFragment();
116116

117+
// NOTE: this acquire synchronizes with `completeFuture`.
117118
auto queueHead = fragment->waitQueue.load(std::memory_order_acquire);
118119
bool contextInitialized = false;
119120
auto escalatedPriority = JobPriority::Unspecified;
@@ -214,6 +215,7 @@ FutureFragment::Status AsyncTask::waitFuture(AsyncTask *waitingTask,
214215
continue;
215216
#else
216217
// Put the waiting task at the beginning of the wait queue.
218+
// NOTE: this acquire-release synchronizes with `completeFuture`.
217219
waitingTask->getNextWaitingTask() = queueHead.getTask();
218220
auto newQueueHead = WaitQueueItem::get(Status::Executing, waitingTask);
219221
if (fragment->waitQueue.compare_exchange_weak(
@@ -267,8 +269,10 @@ void AsyncTask::completeFuture(AsyncContext *context) {
267269
hadErrorResult ? Status::Error : Status::Success,
268270
nullptr
269271
);
272+
273+
// NOTE: this acquire-release synchronizes with `waitFuture`.
270274
auto queueHead = fragment->waitQueue.exchange(
271-
newQueueHead, std::memory_order_acquire);
275+
newQueueHead, std::memory_order_acq_rel);
272276
assert(queueHead.getStatus() == Status::Executing);
273277

274278
// If this is task group child, notify the parent group about the completion.

0 commit comments

Comments
 (0)