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"
@@ -391,15 +392,15 @@ task_future_wait_resume_adapter(SWIFT_ASYNC_CONTEXT AsyncContext *_context) {
391
392
return _context->ResumeParent (_context->Parent );
392
393
}
393
394
394
- // / All `swift_task_create*` variants funnel into this common implementation .
395
+ // / Implementation of task creation .
395
396
// /
396
397
// / If \p isAsyncLetTask is true, the \p closureContext is not heap allocated,
397
398
// / but stack-allocated (and must not be ref-counted).
398
399
// / Also, async-let tasks are not heap allocated, but allocated with the parent
399
400
// / task's stack allocator.
400
- static AsyncTaskAndContext swift_task_create_group_future_commonImpl (
401
+ SWIFT_CC (swift)
402
+ static AsyncTaskAndContext swift_task_createImpl(
401
403
size_t rawFlags,
402
- TaskGroup *group, // TODO: express as an option -- ktoso
403
404
TaskOptionRecord *options,
404
405
const Metadata *futureResultType,
405
406
FutureAsyncSignature::FunctionType *function, void *closureContext,
@@ -410,6 +411,26 @@ static AsyncTaskAndContext swift_task_create_group_future_commonImpl(
410
411
assert (!isAsyncLetTask || isAsyncLetTask == flags.task_isChildTask ());
411
412
assert (!flags.task_isFuture () ||
412
413
initialContextSize >= sizeof (FutureAsyncContext));
414
+
415
+ // Collect the options we know about.
416
+ ExecutorRef executor = ExecutorRef::generic ();
417
+ TaskGroup *group = nullptr ;
418
+ for (auto option = options; option; option = option->getParent ()) {
419
+ switch (option->getKind ()) {
420
+ case TaskOptionRecordKind::Executor:
421
+ executor = cast<ExecutorTaskOptionRecord>(option)->getExecutor ();
422
+ break ;
423
+
424
+ case TaskOptionRecordKind::TaskGroup:
425
+ group = cast<TaskGroupTaskOptionRecord>(option)->getGroup ();
426
+ break ;
427
+
428
+ default :
429
+ // Ignore unknown options.
430
+ break ;
431
+ }
432
+ }
433
+
413
434
assert ((group != nullptr ) == flags.task_isGroupChildTask ());
414
435
415
436
AsyncTask *parent = nullptr ;
@@ -579,14 +600,6 @@ static AsyncTaskAndContext swift_task_create_group_future_commonImpl(
579
600
return {task, initialContext};
580
601
}
581
602
582
- static AsyncTaskAndContext swift_task_create_group_future_common (
583
- size_t flags,
584
- TaskGroup *group,
585
- TaskOptionRecord *options,
586
- const Metadata *futureResultType,
587
- FutureAsyncSignature::FunctionType *function, void *closureContext,
588
- size_t initialContextSize);
589
-
590
603
AsyncTaskAndContext
591
604
swift::swift_task_create_f (
592
605
size_t flags,
@@ -618,12 +631,16 @@ AsyncTaskAndContext swift::swift_task_create_group_future_f(
618
631
TaskOptionRecord *options,
619
632
const Metadata *futureResultType,
620
633
FutureAsyncSignature::FunctionType *function, size_t initialContextSize) {
621
- return swift_task_create_group_future_common (flags,
622
- group,
623
- options,
624
- futureResultType,
625
- function, /* closureContext=*/ nullptr ,
626
- initialContextSize);
634
+ // Wire the group into the options.
635
+ TaskGroupTaskOptionRecord groupRecord (group);
636
+ if (group) {
637
+ groupRecord.Parent = options;
638
+ options = &groupRecord;
639
+ }
640
+
641
+ return swift_task_create (
642
+ flags, options, futureResultType, function, /* closureContext=*/ nullptr ,
643
+ initialContextSize);
627
644
}
628
645
629
646
// / Extract the entry point address and initial context size from an async closure value.
@@ -656,12 +673,8 @@ AsyncTaskAndContext swift::swift_task_create_future(
656
673
SpecialPointerAuthDiscriminators::AsyncFutureFunction
657
674
>(closureEntry, closureContext);
658
675
659
- return swift_task_create_group_future_common (
660
- flags,
661
- /* group*/ nullptr ,
662
- options,
663
- futureResultType,
664
- taskEntry, closureContext,
676
+ return swift_task_create (
677
+ flags, options, futureResultType, taskEntry, closureContext,
665
678
initialContextSize);
666
679
}
667
680
@@ -680,13 +693,9 @@ AsyncTaskAndContext swift::swift_task_create_async_let_future(
680
693
681
694
JobFlags flags (rawFlags);
682
695
flags.task_setIsAsyncLetTask (true );
683
- return swift_task_create_group_future_common (
684
- flags.getOpaqueValue (),
685
- /* group*/ nullptr ,
686
- options,
687
- futureResultType,
688
- taskEntry, closureContext,
689
- initialContextSize);
696
+ return swift_task_create (
697
+ flags.getOpaqueValue (), options, futureResultType,
698
+ taskEntry, closureContext, initialContextSize);
690
699
}
691
700
692
701
AsyncTaskAndContext
@@ -704,12 +713,16 @@ swift::swift_task_create_group_future(
704
713
FutureAsyncSignature,
705
714
SpecialPointerAuthDiscriminators::AsyncFutureFunction
706
715
>(closureEntry, closureContext);
707
- return swift_task_create_group_future_common (
708
- flags,
709
- group,
710
- options,
711
- futureResultType,
712
- taskEntry, closureContext,
716
+
717
+ // Wire the group into the options.
718
+ TaskGroupTaskOptionRecord groupRecord (group);
719
+ if (group) {
720
+ groupRecord.Parent = options;
721
+ options = &groupRecord;
722
+ }
723
+
724
+ return swift_task_create (
725
+ flags, options, futureResultType, taskEntry, closureContext,
713
726
initialContextSize);
714
727
}
715
728
0 commit comments