mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
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 <rjmccall@apple.com>
This commit is contained in:
@@ -114,6 +114,7 @@ FutureFragment::Status AsyncTask::waitFuture(AsyncTask *waitingTask,
|
||||
assert(isFuture());
|
||||
auto fragment = futureFragment();
|
||||
|
||||
// NOTE: this acquire synchronizes with `completeFuture`.
|
||||
auto queueHead = fragment->waitQueue.load(std::memory_order_acquire);
|
||||
bool contextInitialized = false;
|
||||
auto escalatedPriority = JobPriority::Unspecified;
|
||||
@@ -214,6 +215,7 @@ FutureFragment::Status AsyncTask::waitFuture(AsyncTask *waitingTask,
|
||||
continue;
|
||||
#else
|
||||
// Put the waiting task at the beginning of the wait queue.
|
||||
// NOTE: this acquire-release synchronizes with `completeFuture`.
|
||||
waitingTask->getNextWaitingTask() = queueHead.getTask();
|
||||
auto newQueueHead = WaitQueueItem::get(Status::Executing, waitingTask);
|
||||
if (fragment->waitQueue.compare_exchange_weak(
|
||||
@@ -267,8 +269,10 @@ void AsyncTask::completeFuture(AsyncContext *context) {
|
||||
hadErrorResult ? Status::Error : Status::Success,
|
||||
nullptr
|
||||
);
|
||||
|
||||
// NOTE: this acquire-release synchronizes with `waitFuture`.
|
||||
auto queueHead = fragment->waitQueue.exchange(
|
||||
newQueueHead, std::memory_order_acquire);
|
||||
newQueueHead, std::memory_order_acq_rel);
|
||||
assert(queueHead.getStatus() == Status::Executing);
|
||||
|
||||
// If this is task group child, notify the parent group about the completion.
|
||||
|
||||
Reference in New Issue
Block a user