@@ -400,17 +400,28 @@ task_future_wait_resume_adapter(SWIFT_ASYNC_CONTEXT AsyncContext *_context) {
400
400
// / task's stack allocator.
401
401
SWIFT_CC (swift)
402
402
static AsyncTaskAndContext swift_task_createImpl(
403
- size_t rawFlags ,
403
+ size_t rawTaskCreateFlags ,
404
404
TaskOptionRecord *options,
405
405
const Metadata *futureResultType,
406
406
FutureAsyncSignature::FunctionType *function, void *closureContext,
407
407
size_t initialContextSize) {
408
- JobFlags flags (rawFlags);
409
- bool isAsyncLetTask = flags.task_isAsyncLetTask ();
410
- assert ((futureResultType != nullptr ) == flags.task_isFuture ());
411
- assert (!isAsyncLetTask || isAsyncLetTask == flags.task_isChildTask ());
412
- assert (!flags.task_isFuture () ||
413
- initialContextSize >= sizeof (FutureAsyncContext));
408
+ TaskCreateFlags taskCreateFlags (rawTaskCreateFlags);
409
+
410
+ // Propagate task-creation flags to job flags as appropriate.
411
+ JobFlags jobFlags (JobKind::Task, taskCreateFlags.getPriority ());
412
+
413
+ bool isAsyncLetTask = taskCreateFlags.isAsyncLetTask ();
414
+ if (isAsyncLetTask) {
415
+ jobFlags.task_setIsAsyncLetTask (true );
416
+ jobFlags.task_setIsChildTask (true );
417
+ } else {
418
+ jobFlags.task_setIsChildTask (taskCreateFlags.isChildTask ());
419
+ }
420
+
421
+ if (futureResultType) {
422
+ jobFlags.task_setIsFuture (true );
423
+ assert (initialContextSize >= sizeof (FutureAsyncContext));
424
+ }
414
425
415
426
// Collect the options we know about.
416
427
ExecutorRef executor = ExecutorRef::generic ();
@@ -423,32 +434,28 @@ static AsyncTaskAndContext swift_task_createImpl(
423
434
424
435
case TaskOptionRecordKind::TaskGroup:
425
436
group = cast<TaskGroupTaskOptionRecord>(option)->getGroup ();
426
- break ;
427
-
428
- default :
429
- // Ignore unknown options.
437
+ assert (group && " Missing group" );
438
+ jobFlags.task_setIsGroupChildTask (true );
430
439
break ;
431
440
}
432
441
}
433
442
434
- assert ((group != nullptr ) == flags.task_isGroupChildTask ());
435
-
436
443
AsyncTask *parent = nullptr ;
437
- if (flags .task_isChildTask ()) {
444
+ if (jobFlags .task_isChildTask ()) {
438
445
parent = swift_task_getCurrent ();
439
446
assert (parent != nullptr && " creating a child task with no active task" );
440
447
441
448
// Inherit the priority of the parent task if unspecified.
442
- if (flags .getPriority () == JobPriority::Unspecified)
443
- flags .setPriority (parent->getPriority ());
449
+ if (jobFlags .getPriority () == JobPriority::Unspecified)
450
+ jobFlags .setPriority (parent->getPriority ());
444
451
}
445
452
446
453
// Figure out the size of the header.
447
454
size_t headerSize = sizeof (AsyncTask);
448
455
if (parent) {
449
456
headerSize += sizeof (AsyncTask::ChildFragment);
450
457
}
451
- if (flags. task_isGroupChildTask () ) {
458
+ if (group ) {
452
459
headerSize += sizeof (AsyncTask::GroupChildFragment);
453
460
}
454
461
if (futureResultType) {
@@ -521,10 +528,10 @@ static AsyncTaskAndContext swift_task_createImpl(
521
528
// Initialize the refcount bits to "immortal", so that
522
529
// ARC operations don't have any effect on the task.
523
530
task = new (allocation) AsyncTask (&taskHeapMetadata,
524
- InlineRefCounts::Immortal, flags ,
531
+ InlineRefCounts::Immortal, jobFlags ,
525
532
function, initialContext);
526
533
} else {
527
- task = new (allocation) AsyncTask (&taskHeapMetadata, flags ,
534
+ task = new (allocation) AsyncTask (&taskHeapMetadata, jobFlags ,
528
535
function, initialContext);
529
536
}
530
537
@@ -535,7 +542,7 @@ static AsyncTaskAndContext swift_task_createImpl(
535
542
}
536
543
537
544
// Initialize the group child fragment if applicable.
538
- if (flags. task_isGroupChildTask () ) {
545
+ if (group ) {
539
546
auto groupChildFragment = task->groupChildFragment ();
540
547
new (groupChildFragment) AsyncTask::GroupChildFragment (group);
541
548
}
@@ -597,6 +604,16 @@ static AsyncTaskAndContext swift_task_createImpl(
597
604
initialContext->Flags = AsyncContextKind::Ordinary;
598
605
initialContext->Flags .setShouldNotDeallocateInCallee (true );
599
606
607
+ // If we're supposed to copy task locals, do so now.
608
+ if (taskCreateFlags.copyThreadLocals ()) {
609
+ swift_task_localsCopyTo (task);
610
+ }
611
+
612
+ // If we're supposed to enqueue the task, do so now.
613
+ if (taskCreateFlags.enqueueJob ()) {
614
+ swift_task_enqueue (task, executor);
615
+ }
616
+
600
617
return {task, initialContext};
601
618
}
602
619
@@ -625,6 +642,18 @@ AsyncTaskAndContext swift::swift_task_create_future_f(
625
642
function, initialContextSize);
626
643
}
627
644
645
+ // / Temporary hack to convert from job flags to task-creation flags,
646
+ // / until we can eliminate the entry points that operate in terms of job
647
+ // / flags.
648
+ static size_t convertJobFlagsToTaskCreateFlags (size_t rawJobFlags) {
649
+ JobFlags jobFlags (rawJobFlags);
650
+ TaskCreateFlags taskCreateFlags;
651
+ taskCreateFlags.setPriority (jobFlags.getPriority ());
652
+ taskCreateFlags.setIsChildTask (jobFlags.task_isChildTask ());
653
+ taskCreateFlags.setIsAsyncLetTask (jobFlags.task_isAsyncLetTask ());
654
+ return taskCreateFlags.getOpaqueValue ();
655
+ }
656
+
628
657
AsyncTaskAndContext swift::swift_task_create_group_future_f (
629
658
size_t flags,
630
659
TaskGroup *group,
@@ -639,8 +668,8 @@ AsyncTaskAndContext swift::swift_task_create_group_future_f(
639
668
}
640
669
641
670
return swift_task_create (
642
- flags, options, futureResultType, function, /* closureContext= */ nullptr ,
643
- initialContextSize);
671
+ convertJobFlagsToTaskCreateFlags ( flags) , options, futureResultType,
672
+ function, /* closureContext= */ nullptr , initialContextSize);
644
673
}
645
674
646
675
// / Extract the entry point address and initial context size from an async closure value.
@@ -674,8 +703,8 @@ AsyncTaskAndContext swift::swift_task_create_future(
674
703
>(closureEntry, closureContext);
675
704
676
705
return swift_task_create (
677
- flags, options, futureResultType, taskEntry, closureContext ,
678
- initialContextSize);
706
+ convertJobFlagsToTaskCreateFlags ( flags) , options, futureResultType,
707
+ taskEntry, closureContext, initialContextSize);
679
708
}
680
709
681
710
AsyncTaskAndContext swift::swift_task_create_async_let_future (
@@ -694,8 +723,8 @@ AsyncTaskAndContext swift::swift_task_create_async_let_future(
694
723
JobFlags flags (rawFlags);
695
724
flags.task_setIsAsyncLetTask (true );
696
725
return swift_task_create (
697
- flags.getOpaqueValue (), options, futureResultType ,
698
- taskEntry, closureContext, initialContextSize);
726
+ convertJobFlagsToTaskCreateFlags ( flags.getOpaqueValue ()) , options,
727
+ futureResultType, taskEntry, closureContext, initialContextSize);
699
728
}
700
729
701
730
AsyncTaskAndContext
@@ -722,8 +751,8 @@ swift::swift_task_create_group_future(
722
751
}
723
752
724
753
return swift_task_create (
725
- flags, options, futureResultType, taskEntry, closureContext ,
726
- initialContextSize);
754
+ convertJobFlagsToTaskCreateFlags ( flags) , options, futureResultType,
755
+ taskEntry, closureContext, initialContextSize);
727
756
}
728
757
729
758
SWIFT_CC (swiftasync)
0 commit comments