@@ -114,6 +114,12 @@ class TaskGroupImpl: public TaskGroupTaskStatusRecord {
114
114
// / until a next() call eventually picks it up.
115
115
AsyncTask *retainedTask;
116
116
117
+ bool isStorageAccessible () {
118
+ return status == PollStatus::Success ||
119
+ status == PollStatus::Error ||
120
+ status == PollStatus::Empty;
121
+ }
122
+
117
123
static PollResult get (AsyncTask *asyncTask, bool hadErrorResult) {
118
124
auto fragment = asyncTask->futureFragment ();
119
125
return PollResult{
@@ -127,15 +133,6 @@ class TaskGroupImpl: public TaskGroupTaskStatusRecord {
127
133
/* task*/ asyncTask
128
134
};
129
135
}
130
-
131
- static PollResult getEmpty (const Metadata *successType) {
132
- return PollResult{
133
- /* status*/ PollStatus::Success,
134
- /* storage*/ nullptr ,
135
- /* successType*/ successType,
136
- /* task*/ nullptr
137
- };
138
- }
139
136
};
140
137
141
138
// / An item within the message queue of a group.
@@ -429,17 +426,6 @@ class TaskGroupImpl: public TaskGroupTaskStatusRecord {
429
426
// / or a `PollStatus::MustWait` result if there are tasks in flight
430
427
// / and the waitingTask eventually be woken up by a completion.
431
428
PollResult poll (AsyncTask *waitingTask);
432
-
433
- // / A `discardResults` TaskGroup is not able to wait on individual completions,
434
- // / instead, it can only await on "all pending tasks have been processed".
435
- // /
436
- // /
437
- // / If unable to complete the waiting task immediately (with an readily
438
- // / available completed task), either returns an `PollStatus::Empty`
439
- // / result if it is known that no pending tasks in the group,
440
- // / or a `PollStatus::MustWait` result if there are tasks in flight
441
- // / and the waitingTask eventually be woken up by a completion.
442
- PollResult waitAll (AsyncTask *waitingTask);
443
429
};
444
430
445
431
} // end anonymous namespace
@@ -474,7 +460,7 @@ TaskGroupTaskStatusRecord *TaskGroup::getTaskRecord() {
474
460
475
461
// Initializes into the preallocated _group an actual TaskGroupImpl.
476
462
SWIFT_CC (swift)
477
- static void swift_taskGroup_initializeWithFlagsImpl( size_t flags, TaskGroup *group, const Metadata *T) {
463
+ static void swift_taskGroup_initializeImpl( TaskGroup *group, const Metadata *T) {
478
464
SWIFT_TASK_DEBUG_LOG (" creating task group = %p" , group);
479
465
480
466
TaskGroupImpl *impl = new (group) TaskGroupImpl (T);
@@ -489,12 +475,6 @@ static void swift_taskGroup_initializeWithFlagsImpl(size_t flags, TaskGroup *gro
489
475
if (!notCancelled) impl->statusCancel ();
490
476
}
491
477
492
- // Initializes into the preallocated _group an actual TaskGroupImpl.
493
- SWIFT_CC (swift)
494
- static void swift_taskGroup_initializeImpl(TaskGroup *group, const Metadata *T) {
495
- swift_taskGroup_initializeWithFlagsImpl (0 , group, T);
496
- }
497
-
498
478
// =============================================================================
499
479
// ==== add / attachChild ------------------------------------------------------
500
480
@@ -566,7 +546,7 @@ static void fillGroupNextResult(TaskFutureWaitAsyncContext *context,
566
546
}
567
547
568
548
case PollStatus::Empty: {
569
- // Initialize the result as a .none Optional<Success>.
549
+ // Initialize the result as a nil Optional<Success>.
570
550
const Metadata *successType = result.successType ;
571
551
OpaqueValue *destPtr = context->successResultPointer ;
572
552
successType->vw_storeEnumTagSinglePayload (destPtr, 1 , 1 );
@@ -575,13 +555,6 @@ static void fillGroupNextResult(TaskFutureWaitAsyncContext *context,
575
555
}
576
556
}
577
557
578
- static void fillGroupNextNilResult (TaskFutureWaitAsyncContext *context) {
579
- // / Fill in the result value with 'nil'
580
- const Metadata *successType = result.successType ;
581
- OpaqueValue *destPtr = context->successResultPointer ;
582
- successType->vw_storeEnumTagSinglePayload (destPtr, 1 , 1 );
583
- }
584
-
585
558
void TaskGroupImpl::offer (AsyncTask *completedTask, AsyncContext *context) {
586
559
assert (completedTask);
587
560
assert (completedTask->isFuture ());
@@ -598,7 +571,6 @@ void TaskGroupImpl::offer(AsyncTask *completedTask, AsyncContext *context) {
598
571
// W:n R:0 P:1 -> W:y R:1 P:1 // complete immediately
599
572
// W:n R:0 P:1 -> W:y R:1 P:3 // complete immediately, 2 more pending tasks
600
573
auto assumed = statusAddReadyAssumeAcquire ();
601
- SWIFT_TASK_DEBUG_LOG (" offer task %p to group(%p), tasks pending = %d" , completedTask, assumed.pendingTasks ());
602
574
603
575
auto asyncContextPrefix = reinterpret_cast <FutureAsyncContextPrefix *>(
604
576
reinterpret_cast <char *>(context) - sizeof (FutureAsyncContextPrefix));
@@ -668,7 +640,6 @@ void TaskGroupImpl::offer(AsyncTask *completedTask, AsyncContext *context) {
668
640
assert (completedTask == readyItem.getTask ());
669
641
assert (readyItem.getTask ()->isFuture ());
670
642
readyQueue.enqueue (readyItem);
671
-
672
643
mutex.unlock (); // TODO: remove fragment lock, and use status for synchronization
673
644
return ;
674
645
}
@@ -713,20 +684,20 @@ static void swift_taskGroup_wait_next_throwingImpl(
713
684
waitingTask->ResumeTask = task_group_wait_resume_adapter;
714
685
waitingTask->ResumeContext = rawContext;
715
686
716
- auto group = asImpl (_group);
717
- assert (group && " swift_taskGroup_wait_next_throwing was passed context without group!" );
718
-
719
687
auto context = static_cast <TaskFutureWaitAsyncContext *>(rawContext);
720
688
context->ResumeParent =
721
689
reinterpret_cast <TaskContinuationFunction *>(resumeFunction);
722
690
context->Parent = callerContext;
723
691
context->errorResult = nullptr ;
724
692
context->successResultPointer = resultPointer;
725
693
694
+ auto group = asImpl (_group);
695
+ assert (group && " swift_taskGroup_wait_next_throwing was passed context without group!" );
696
+
726
697
PollResult polled = group->poll (waitingTask);
727
698
switch (polled.status ) {
728
699
case PollStatus::MustWait:
729
- SWIFT_TASK_DEBUG_LOG (" poll group = %p, tasks ready = 0 , waiting task = %p" ,
700
+ SWIFT_TASK_DEBUG_LOG (" poll group = %p, no ready tasks , waiting task = %p" ,
730
701
group, waitingTask);
731
702
// The waiting task has been queued on the channel,
732
703
// there were pending tasks so it will be woken up eventually.
@@ -746,8 +717,8 @@ static void swift_taskGroup_wait_next_throwingImpl(
746
717
747
718
if (auto completedTask = polled.retainedTask ) {
748
719
// it would be null for PollStatus::Empty, then we don't need to release
749
- group->detachChild (completedTask );
750
- swift_release (completedTask );
720
+ group->detachChild (polled. retainedTask );
721
+ swift_release (polled. retainedTask );
751
722
}
752
723
return waitingTask->runInFullyEstablishedContext ();
753
724
}
@@ -783,13 +754,13 @@ PollResult TaskGroupImpl::poll(AsyncTask *waitingTask) {
783
754
784
755
// ==== 2) Ready task was polled, return with it immediately -----------------
785
756
if (assumed.readyTasks ()) {
786
- SWIFT_TASK_DEBUG_LOG (" poll group = %p, tasks ready=%d, pending= %d" ,
787
- this , assumed.readyTasks (), assumed. pendingTasks () );
757
+ SWIFT_TASK_DEBUG_LOG (" poll group = %p, group has ready tasks = %d" ,
758
+ this , assumed.readyTasks ());
788
759
789
760
auto assumedStatus = assumed.status ;
790
761
auto newStatus = TaskGroupImpl::GroupStatus{assumedStatus};
791
762
if (status.compare_exchange_strong (
792
- assumedStatus, newStatus.completingPendingReadyWaiting (this ).status ,
763
+ assumedStatus, newStatus.completingPendingReadyWaiting ().status ,
793
764
/* success*/ std::memory_order_relaxed,
794
765
/* failure*/ std::memory_order_acquire)) {
795
766
@@ -846,7 +817,7 @@ PollResult TaskGroupImpl::poll(AsyncTask *waitingTask) {
846
817
}
847
818
848
819
// ==== 3) Add to wait queue -------------------------------------------------
849
- assert (assumed.readyTasks (this ) == 0 );
820
+ assert (assumed.readyTasks () == 0 );
850
821
_swift_tsan_release (static_cast <Job *>(waitingTask));
851
822
while (true ) {
852
823
if (!hasSuspended) {
@@ -868,13 +839,15 @@ PollResult TaskGroupImpl::poll(AsyncTask *waitingTask) {
868
839
}
869
840
870
841
// =============================================================================
871
- // ==== Task Group status and flag checks -------------------------------------
842
+ // ==== isEmpty --------------------------- -------------------------------------
872
843
873
844
SWIFT_CC (swift)
874
845
static bool swift_taskGroup_isEmptyImpl(TaskGroup *group) {
875
846
return asImpl (group)->isEmpty ();
876
847
}
877
848
849
+ // =============================================================================
850
+ // ==== isCancelled ------------------------------------------------------------
878
851
SWIFT_CC (swift)
879
852
static bool swift_taskGroup_isCancelledImpl(TaskGroup *group) {
880
853
return asImpl (group)->isCancelled ();
0 commit comments