18
18
#include " swift/Runtime/Concurrency.h"
19
19
#include " swift/ABI/Task.h"
20
20
#include " swift/ABI/TaskLocal.h"
21
+ #include " swift/ABI/TaskOptions.h"
21
22
#include " swift/ABI/Metadata.h"
22
23
#include " swift/Runtime/Mutex.h"
23
24
#include " swift/Runtime/HeapObject.h"
@@ -396,15 +397,15 @@ task_future_wait_resume_adapter(SWIFT_ASYNC_CONTEXT AsyncContext *_context) {
396
397
return _context->ResumeParent (_context->Parent );
397
398
}
398
399
399
- // / All `swift_task_create*` variants funnel into this common implementation .
400
+ // / Implementation of task creation .
400
401
// /
401
402
// / If \p isAsyncLetTask is true, the \p closureContext is not heap allocated,
402
403
// / but stack-allocated (and must not be ref-counted).
403
404
// / Also, async-let tasks are not heap allocated, but allocated with the parent
404
405
// / task's stack allocator.
405
- static AsyncTaskAndContext swift_task_create_group_future_commonImpl (
406
+ SWIFT_CC (swift)
407
+ static AsyncTaskAndContext swift_task_createImpl(
406
408
size_t rawFlags,
407
- TaskGroup *group, // TODO: express as an option -- ktoso
408
409
TaskOptionRecord *options,
409
410
const Metadata *futureResultType,
410
411
FutureAsyncSignature::FunctionType *function, void *closureContext,
@@ -415,6 +416,26 @@ static AsyncTaskAndContext swift_task_create_group_future_commonImpl(
415
416
assert (!isAsyncLetTask || isAsyncLetTask == flags.task_isChildTask ());
416
417
assert (!flags.task_isFuture () ||
417
418
initialContextSize >= sizeof (FutureAsyncContext));
419
+
420
+ // Collect the options we know about.
421
+ ExecutorRef executor = ExecutorRef::generic ();
422
+ TaskGroup *group = nullptr ;
423
+ for (auto option = options; option; option = option->getParent ()) {
424
+ switch (option->getKind ()) {
425
+ case TaskOptionRecordKind::Executor:
426
+ executor = cast<ExecutorTaskOptionRecord>(option)->getExecutor ();
427
+ break ;
428
+
429
+ case TaskOptionRecordKind::TaskGroup:
430
+ group = cast<TaskGroupTaskOptionRecord>(option)->getGroup ();
431
+ break ;
432
+
433
+ default :
434
+ // Ignore unknown options.
435
+ break ;
436
+ }
437
+ }
438
+
418
439
assert ((group != nullptr ) == flags.task_isGroupChildTask ());
419
440
420
441
AsyncTask *parent = nullptr ;
@@ -586,14 +607,6 @@ static AsyncTaskAndContext swift_task_create_group_future_commonImpl(
586
607
return {task, initialContext};
587
608
}
588
609
589
- static AsyncTaskAndContext swift_task_create_group_future_common (
590
- size_t flags,
591
- TaskGroup *group,
592
- TaskOptionRecord *options,
593
- const Metadata *futureResultType,
594
- FutureAsyncSignature::FunctionType *function, void *closureContext,
595
- size_t initialContextSize);
596
-
597
610
AsyncTaskAndContext
598
611
swift::swift_task_create_f (
599
612
size_t flags,
@@ -625,12 +638,16 @@ AsyncTaskAndContext swift::swift_task_create_group_future_f(
625
638
TaskOptionRecord *options,
626
639
const Metadata *futureResultType,
627
640
FutureAsyncSignature::FunctionType *function, size_t initialContextSize) {
628
- return swift_task_create_group_future_common (flags,
629
- group,
630
- options,
631
- futureResultType,
632
- function, /* closureContext=*/ nullptr ,
633
- initialContextSize);
641
+ // Wire the group into the options.
642
+ TaskGroupTaskOptionRecord groupRecord (group);
643
+ if (group) {
644
+ groupRecord.Parent = options;
645
+ options = &groupRecord;
646
+ }
647
+
648
+ return swift_task_create (
649
+ flags, options, futureResultType, function, /* closureContext=*/ nullptr ,
650
+ initialContextSize);
634
651
}
635
652
636
653
// / Extract the entry point address and initial context size from an async closure value.
@@ -663,12 +680,8 @@ AsyncTaskAndContext swift::swift_task_create_future(
663
680
SpecialPointerAuthDiscriminators::AsyncFutureFunction
664
681
>(closureEntry, closureContext);
665
682
666
- return swift_task_create_group_future_common (
667
- flags,
668
- /* group*/ nullptr ,
669
- options,
670
- futureResultType,
671
- taskEntry, closureContext,
683
+ return swift_task_create (
684
+ flags, options, futureResultType, taskEntry, closureContext,
672
685
initialContextSize);
673
686
}
674
687
@@ -687,13 +700,9 @@ AsyncTaskAndContext swift::swift_task_create_async_let_future(
687
700
688
701
JobFlags flags (rawFlags);
689
702
flags.task_setIsAsyncLetTask (true );
690
- return swift_task_create_group_future_common (
691
- flags.getOpaqueValue (),
692
- /* group*/ nullptr ,
693
- options,
694
- futureResultType,
695
- taskEntry, closureContext,
696
- initialContextSize);
703
+ return swift_task_create (
704
+ flags.getOpaqueValue (), options, futureResultType,
705
+ taskEntry, closureContext, initialContextSize);
697
706
}
698
707
699
708
AsyncTaskAndContext
@@ -711,12 +720,16 @@ swift::swift_task_create_group_future(
711
720
FutureAsyncSignature,
712
721
SpecialPointerAuthDiscriminators::AsyncFutureFunction
713
722
>(closureEntry, closureContext);
714
- return swift_task_create_group_future_common (
715
- flags,
716
- group,
717
- options,
718
- futureResultType,
719
- taskEntry, closureContext,
723
+
724
+ // Wire the group into the options.
725
+ TaskGroupTaskOptionRecord groupRecord (group);
726
+ if (group) {
727
+ groupRecord.Parent = options;
728
+ options = &groupRecord;
729
+ }
730
+
731
+ return swift_task_create (
732
+ flags, options, futureResultType, taskEntry, closureContext,
720
733
initialContextSize);
721
734
}
722
735
0 commit comments