@@ -405,17 +405,28 @@ task_future_wait_resume_adapter(SWIFT_ASYNC_CONTEXT AsyncContext *_context) {
405
405
// / task's stack allocator.
406
406
SWIFT_CC (swift)
407
407
static AsyncTaskAndContext swift_task_createImpl(
408
- size_t rawFlags ,
408
+ size_t rawTaskCreateFlags ,
409
409
TaskOptionRecord *options,
410
410
const Metadata *futureResultType,
411
411
FutureAsyncSignature::FunctionType *function, void *closureContext,
412
412
size_t initialContextSize) {
413
- JobFlags flags (rawFlags);
414
- bool isAsyncLetTask = flags.task_isAsyncLetTask ();
415
- assert ((futureResultType != nullptr ) == flags.task_isFuture ());
416
- assert (!isAsyncLetTask || isAsyncLetTask == flags.task_isChildTask ());
417
- assert (!flags.task_isFuture () ||
418
- initialContextSize >= sizeof (FutureAsyncContext));
413
+ TaskCreateFlags taskCreateFlags (rawTaskCreateFlags);
414
+
415
+ // Propagate task-creation flags to job flags as appropriate.
416
+ JobFlags jobFlags (JobKind::Task, taskCreateFlags.getPriority ());
417
+
418
+ bool isAsyncLetTask = taskCreateFlags.isAsyncLetTask ();
419
+ if (isAsyncLetTask) {
420
+ jobFlags.task_setIsAsyncLetTask (true );
421
+ jobFlags.task_setIsChildTask (true );
422
+ } else {
423
+ jobFlags.task_setIsChildTask (taskCreateFlags.isChildTask ());
424
+ }
425
+
426
+ if (futureResultType) {
427
+ jobFlags.task_setIsFuture (true );
428
+ assert (initialContextSize >= sizeof (FutureAsyncContext));
429
+ }
419
430
420
431
// Collect the options we know about.
421
432
ExecutorRef executor = ExecutorRef::generic ();
@@ -428,32 +439,28 @@ static AsyncTaskAndContext swift_task_createImpl(
428
439
429
440
case TaskOptionRecordKind::TaskGroup:
430
441
group = cast<TaskGroupTaskOptionRecord>(option)->getGroup ();
431
- break ;
432
-
433
- default :
434
- // Ignore unknown options.
442
+ assert (group && " Missing group" );
443
+ jobFlags.task_setIsGroupChildTask (true );
435
444
break ;
436
445
}
437
446
}
438
447
439
- assert ((group != nullptr ) == flags.task_isGroupChildTask ());
440
-
441
448
AsyncTask *parent = nullptr ;
442
- if (flags .task_isChildTask ()) {
449
+ if (jobFlags .task_isChildTask ()) {
443
450
parent = swift_task_getCurrent ();
444
451
assert (parent != nullptr && " creating a child task with no active task" );
445
452
446
453
// Inherit the priority of the parent task if unspecified.
447
- if (flags .getPriority () == JobPriority::Unspecified)
448
- flags .setPriority (parent->getPriority ());
454
+ if (jobFlags .getPriority () == JobPriority::Unspecified)
455
+ jobFlags .setPriority (parent->getPriority ());
449
456
}
450
457
451
458
// Figure out the size of the header.
452
459
size_t headerSize = sizeof (AsyncTask);
453
460
if (parent) {
454
461
headerSize += sizeof (AsyncTask::ChildFragment);
455
462
}
456
- if (flags. task_isGroupChildTask () ) {
463
+ if (group ) {
457
464
headerSize += sizeof (AsyncTask::GroupChildFragment);
458
465
}
459
466
if (futureResultType) {
@@ -527,10 +534,10 @@ static AsyncTaskAndContext swift_task_createImpl(
527
534
// Initialize the refcount bits to "immortal", so that
528
535
// ARC operations don't have any effect on the task.
529
536
task = new (allocation) AsyncTask (&taskHeapMetadata,
530
- InlineRefCounts::Immortal, flags ,
537
+ InlineRefCounts::Immortal, jobFlags ,
531
538
function, initialContext);
532
539
} else {
533
- task = new (allocation) AsyncTask (&taskHeapMetadata, flags ,
540
+ task = new (allocation) AsyncTask (&taskHeapMetadata, jobFlags ,
534
541
function, initialContext);
535
542
}
536
543
@@ -541,7 +548,7 @@ static AsyncTaskAndContext swift_task_createImpl(
541
548
}
542
549
543
550
// Initialize the group child fragment if applicable.
544
- if (flags. task_isGroupChildTask () ) {
551
+ if (group ) {
545
552
auto groupChildFragment = task->groupChildFragment ();
546
553
new (groupChildFragment) AsyncTask::GroupChildFragment (group);
547
554
}
@@ -604,6 +611,16 @@ static AsyncTaskAndContext swift_task_createImpl(
604
611
initialContext->Flags = AsyncContextKind::Ordinary;
605
612
initialContext->Flags .setShouldNotDeallocateInCallee (true );
606
613
614
+ // If we're supposed to copy task locals, do so now.
615
+ if (taskCreateFlags.copyThreadLocals ()) {
616
+ swift_task_localsCopyTo (task);
617
+ }
618
+
619
+ // If we're supposed to enqueue the task, do so now.
620
+ if (taskCreateFlags.enqueueJob ()) {
621
+ swift_task_enqueue (task, executor);
622
+ }
623
+
607
624
return {task, initialContext};
608
625
}
609
626
@@ -632,6 +649,18 @@ AsyncTaskAndContext swift::swift_task_create_future_f(
632
649
function, initialContextSize);
633
650
}
634
651
652
+ // / Temporary hack to convert from job flags to task-creation flags,
653
+ // / until we can eliminate the entry points that operate in terms of job
654
+ // / flags.
655
+ static size_t convertJobFlagsToTaskCreateFlags (size_t rawJobFlags) {
656
+ JobFlags jobFlags (rawJobFlags);
657
+ TaskCreateFlags taskCreateFlags;
658
+ taskCreateFlags.setPriority (jobFlags.getPriority ());
659
+ taskCreateFlags.setIsChildTask (jobFlags.task_isChildTask ());
660
+ taskCreateFlags.setIsAsyncLetTask (jobFlags.task_isAsyncLetTask ());
661
+ return taskCreateFlags.getOpaqueValue ();
662
+ }
663
+
635
664
AsyncTaskAndContext swift::swift_task_create_group_future_f (
636
665
size_t flags,
637
666
TaskGroup *group,
@@ -646,8 +675,8 @@ AsyncTaskAndContext swift::swift_task_create_group_future_f(
646
675
}
647
676
648
677
return swift_task_create (
649
- flags, options, futureResultType, function, /* closureContext= */ nullptr ,
650
- initialContextSize);
678
+ convertJobFlagsToTaskCreateFlags ( flags) , options, futureResultType,
679
+ function, /* closureContext= */ nullptr , initialContextSize);
651
680
}
652
681
653
682
// / Extract the entry point address and initial context size from an async closure value.
@@ -681,8 +710,8 @@ AsyncTaskAndContext swift::swift_task_create_future(
681
710
>(closureEntry, closureContext);
682
711
683
712
return swift_task_create (
684
- flags, options, futureResultType, taskEntry, closureContext ,
685
- initialContextSize);
713
+ convertJobFlagsToTaskCreateFlags ( flags) , options, futureResultType,
714
+ taskEntry, closureContext, initialContextSize);
686
715
}
687
716
688
717
AsyncTaskAndContext swift::swift_task_create_async_let_future (
@@ -701,8 +730,8 @@ AsyncTaskAndContext swift::swift_task_create_async_let_future(
701
730
JobFlags flags (rawFlags);
702
731
flags.task_setIsAsyncLetTask (true );
703
732
return swift_task_create (
704
- flags.getOpaqueValue (), options, futureResultType ,
705
- taskEntry, closureContext, initialContextSize);
733
+ convertJobFlagsToTaskCreateFlags ( flags.getOpaqueValue ()) , options,
734
+ futureResultType, taskEntry, closureContext, initialContextSize);
706
735
}
707
736
708
737
AsyncTaskAndContext
@@ -729,8 +758,8 @@ swift::swift_task_create_group_future(
729
758
}
730
759
731
760
return swift_task_create (
732
- flags, options, futureResultType, taskEntry, closureContext ,
733
- initialContextSize);
761
+ convertJobFlagsToTaskCreateFlags ( flags) , options, futureResultType,
762
+ taskEntry, closureContext, initialContextSize);
734
763
}
735
764
736
765
SWIFT_CC (swiftasync)
0 commit comments