Skip to content

Commit 78a8fc8

Browse files
committed
The asserts in preprocessQueue assume that the only reason we are
preprocessing is due to running into a concurrent enqueuer while draining. However, sometimes we can go into this code path because compare_exchange_weak failed spuriously. We need to account the fact that compare_exchange_weak can fail spuriously. Also add more asserts. Radar-Id: rdar://problem/89236911
1 parent a3e3c3f commit 78a8fc8

File tree

1 file changed

+7
-0
lines changed

1 file changed

+7
-0
lines changed

stdlib/public/Concurrency/Actor.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,8 @@ static Job *
10311031
preprocessQueue(JobRef unprocessedStart, JobRef unprocessedEnd, Job *existingProcessedJobsToMergeInto)
10321032
{
10331033
assert(existingProcessedJobsToMergeInto != NULL);
1034+
assert(unprocessedStart.needsPreprocessing());
1035+
assert(unprocessedStart.getAsJob() != unprocessedEnd.getAsJob());
10341036

10351037
// Build up a list of jobs we need to preprocess
10361038
using ListMerger = swift::ListMerger<Job*, JobQueueTraits>;
@@ -1423,6 +1425,11 @@ Job * DefaultActorImpl::drainOne() {
14231425
return firstJob;
14241426
}
14251427

1428+
// We failed the weak cmpxchg spuriously, go through loop again.
1429+
if (oldState.getFirstJob().getAsJob() == jobToPreprocessFrom.getAsJob()) {
1430+
continue;
1431+
}
1432+
14261433
// There were new items concurrently added to the queue. We need to
14271434
// preprocess the newly added unprocessed items and merge them to the already
14281435
// preprocessed list.

0 commit comments

Comments
 (0)