Skip to content

Commit 81ce2dc

Browse files
committed
Create a separate set of task creation flags for swift_task_create.
The flags that are useful for task creation are a bit different from the flags that go on a job. Create a separate flag set for task creation and use that in the API for `swift_task_create`. For now, have the callers do the remapping.
1 parent 8562388 commit 81ce2dc

File tree

5 files changed

+107
-75
lines changed

5 files changed

+107
-75
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2022,6 +2022,42 @@ enum class JobPriority : size_t {
20222022
Unspecified = 0x00,
20232023
};
20242024

2025+
/// Flags for task creation.
2026+
class TaskCreateFlags : public FlagSet<size_t> {
2027+
public:
2028+
enum {
2029+
Priority = 0,
2030+
Priority_width = 8,
2031+
2032+
Task_IsChildTask = 8,
2033+
Task_IsAsyncLetTask = 9,
2034+
Task_CopyThreadLocals = 10,
2035+
Task_InheritContext = 11,
2036+
Task_EnqueueJob = 12,
2037+
};
2038+
2039+
explicit constexpr TaskCreateFlags(size_t bits) : FlagSet(bits) {}
2040+
constexpr TaskCreateFlags() {}
2041+
2042+
FLAGSET_DEFINE_FIELD_ACCESSORS(Priority, Priority_width, JobPriority,
2043+
getPriority, setPriority)
2044+
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsChildTask,
2045+
isChildTask,
2046+
setIsChildTask)
2047+
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsAsyncLetTask,
2048+
isAsyncLetTask,
2049+
setIsAsyncLetTask)
2050+
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_CopyThreadLocals,
2051+
copyThreadLocals,
2052+
setCopyThreadLocals)
2053+
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_InheritContext,
2054+
inheritContext,
2055+
setInheritContext)
2056+
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_EnqueueJob,
2057+
enqueueJob,
2058+
setEnqueueJob)
2059+
};
2060+
20252061
/// Flags for schedulable jobs.
20262062
class JobFlags : public FlagSet<uint32_t> {
20272063
public:
@@ -2039,7 +2075,7 @@ class JobFlags : public FlagSet<uint32_t> {
20392075
Task_IsChildTask = 24,
20402076
Task_IsFuture = 25,
20412077
Task_IsGroupChildTask = 26,
2042-
Task_IsContinuingAsyncTask = 27,
2078+
// 27 is currently unused
20432079
Task_IsAsyncLetTask = 28,
20442080
};
20452081

@@ -2070,9 +2106,6 @@ class JobFlags : public FlagSet<uint32_t> {
20702106
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsGroupChildTask,
20712107
task_isGroupChildTask,
20722108
task_setIsGroupChildTask)
2073-
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsContinuingAsyncTask,
2074-
task_isContinuingAsyncTask,
2075-
task_setIsContinuingAsyncTask)
20762109
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsAsyncLetTask,
20772110
task_isAsyncLetTask,
20782111
task_setIsAsyncLetTask)

include/swift/Runtime/Concurrency.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ AsyncTaskAndContext swift_task_create_group_future_f(
8787
/// Create a task object.
8888
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
8989
AsyncTaskAndContext swift_task_create(
90-
size_t flags,
90+
size_t taskCreateFlags,
9191
TaskOptionRecord *options,
9292
const Metadata *futureResultType,
9393
FutureAsyncSignature::FunctionType *function, void *closureContext,

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,20 +1547,6 @@ FUNCTION(TaskCancel,
15471547
ARGS(SwiftTaskPtrTy),
15481548
ATTRS(NoUnwind, ArgMemOnly))
15491549

1550-
// AsyncTaskAndContext swift_task_create_f(
1551-
// size_t flags,
1552-
// TaskOptionRecord *options,
1553-
// TaskContinuationFunction* function, size_t contextSize);
1554-
FUNCTION(TaskCreateFunc,
1555-
swift_task_create_f, SwiftCC,
1556-
ConcurrencyAvailability,
1557-
RETURNS(AsyncTaskAndContextTy),
1558-
ARGS(SizeTy,
1559-
SwiftTaskOptionRecordPtrTy,
1560-
TaskContinuationFunctionPtrTy,
1561-
SizeTy),
1562-
ATTRS(NoUnwind, ArgMemOnly))
1563-
15641550
// AsyncTaskAndContext swift_task_create_future(
15651551
// size_t flags,
15661552
// TaskOptionRecord *options,
@@ -1577,22 +1563,6 @@ FUNCTION(TaskCreateFuture,
15771563
RefCountedPtrTy),
15781564
ATTRS(NoUnwind, ArgMemOnly))
15791565

1580-
// AsyncTaskAndContext swift_task_create_future_f(
1581-
// size_t flags,
1582-
// TaskOptionRecord *options,
1583-
// const Metadata *futureResultType,
1584-
// TaskContinuationFunction *function, size_t contextSize);
1585-
FUNCTION(TaskCreateFutureFunc,
1586-
swift_task_create_future_f, SwiftCC,
1587-
ConcurrencyAvailability,
1588-
RETURNS(AsyncTaskAndContextTy),
1589-
ARGS(SizeTy,
1590-
SwiftTaskOptionRecordPtrTy,
1591-
TypeMetadataPtrTy,
1592-
TaskContinuationFunctionPtrTy,
1593-
SizeTy),
1594-
ATTRS(NoUnwind, ArgMemOnly))
1595-
15961566
// AsyncTaskAndContext swift_task_create_group_future(
15971567
// size_t flags,
15981568
// TaskGroup *group,
@@ -1611,21 +1581,21 @@ FUNCTION(TaskCreateGroupFuture,
16111581
RefCountedPtrTy),
16121582
ATTRS(NoUnwind, ArgMemOnly))
16131583

1614-
// AsyncTaskAndContext swift_task_create_group_future_f(
1615-
// size_t flags,
1616-
// TaskGroup *group,
1617-
// TaskOptionRecord *options
1584+
// AsyncTaskAndContext swift_task_create(
1585+
// size_t taskCreateFlags,
1586+
// TaskOptionRecord *options,
16181587
// const Metadata *futureResultType,
1619-
// TaskContinuationFunction *function, size_t contextSize);
1620-
FUNCTION(TaskCreateGroupFutureFunc,
1621-
swift_task_create_group_future_f, SwiftCC,
1588+
// void *closureEntry, HeapObject *closureContext,
1589+
// size_t initialContextSize);
1590+
FUNCTION(TaskCreate,
1591+
swift_task_create, SwiftCC,
16221592
ConcurrencyAvailability,
16231593
RETURNS(AsyncTaskAndContextTy),
16241594
ARGS(SizeTy,
1625-
SwiftTaskGroupPtrTy,
16261595
SwiftTaskOptionRecordPtrTy,
16271596
TypeMetadataPtrTy,
1628-
TaskContinuationFunctionPtrTy,
1597+
Int8PtrTy,
1598+
RefCountedPtrTy,
16291599
SizeTy),
16301600
ATTRS(NoUnwind, ArgMemOnly))
16311601

stdlib/public/CompatibilityOverride/CompatibilityOverrideConcurrency.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,14 @@ OVERRIDE_ACTOR(task_switch, void,
9898

9999
OVERRIDE_TASK(task_create, AsyncTaskAndContext,
100100
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift), swift::,
101-
(size_t flags,
101+
(size_t taskCreateFlags,
102102
TaskOptionRecord *options,
103103
const Metadata *futureResultType,
104104
FutureAsyncSignature::FunctionType *function,
105105
void *closureContext,
106106
size_t initialContextSize),
107-
(flags, options, futureResultType, function, closureContext,
108-
initialContextSize))
107+
(taskCreateFlags, options, futureResultType, function,
108+
closureContext, initialContextSize))
109109

110110
OVERRIDE_TASK(task_future_wait, void, SWIFT_EXPORT_FROM(swift_Concurrency),
111111
SWIFT_CC(swiftasync), swift::,

stdlib/public/Concurrency/Task.cpp

Lines changed: 57 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -400,17 +400,28 @@ task_future_wait_resume_adapter(SWIFT_ASYNC_CONTEXT AsyncContext *_context) {
400400
/// task's stack allocator.
401401
SWIFT_CC(swift)
402402
static AsyncTaskAndContext swift_task_createImpl(
403-
size_t rawFlags,
403+
size_t rawTaskCreateFlags,
404404
TaskOptionRecord *options,
405405
const Metadata *futureResultType,
406406
FutureAsyncSignature::FunctionType *function, void *closureContext,
407407
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+
}
414425

415426
// Collect the options we know about.
416427
ExecutorRef executor = ExecutorRef::generic();
@@ -423,32 +434,28 @@ static AsyncTaskAndContext swift_task_createImpl(
423434

424435
case TaskOptionRecordKind::TaskGroup:
425436
group = cast<TaskGroupTaskOptionRecord>(option)->getGroup();
426-
break;
427-
428-
default:
429-
// Ignore unknown options.
437+
assert(group && "Missing group");
438+
jobFlags.task_setIsGroupChildTask(true);
430439
break;
431440
}
432441
}
433442

434-
assert((group != nullptr) == flags.task_isGroupChildTask());
435-
436443
AsyncTask *parent = nullptr;
437-
if (flags.task_isChildTask()) {
444+
if (jobFlags.task_isChildTask()) {
438445
parent = swift_task_getCurrent();
439446
assert(parent != nullptr && "creating a child task with no active task");
440447

441448
// 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());
444451
}
445452

446453
// Figure out the size of the header.
447454
size_t headerSize = sizeof(AsyncTask);
448455
if (parent) {
449456
headerSize += sizeof(AsyncTask::ChildFragment);
450457
}
451-
if (flags.task_isGroupChildTask()) {
458+
if (group) {
452459
headerSize += sizeof(AsyncTask::GroupChildFragment);
453460
}
454461
if (futureResultType) {
@@ -521,10 +528,10 @@ static AsyncTaskAndContext swift_task_createImpl(
521528
// Initialize the refcount bits to "immortal", so that
522529
// ARC operations don't have any effect on the task.
523530
task = new(allocation) AsyncTask(&taskHeapMetadata,
524-
InlineRefCounts::Immortal, flags,
531+
InlineRefCounts::Immortal, jobFlags,
525532
function, initialContext);
526533
} else {
527-
task = new(allocation) AsyncTask(&taskHeapMetadata, flags,
534+
task = new(allocation) AsyncTask(&taskHeapMetadata, jobFlags,
528535
function, initialContext);
529536
}
530537

@@ -535,7 +542,7 @@ static AsyncTaskAndContext swift_task_createImpl(
535542
}
536543

537544
// Initialize the group child fragment if applicable.
538-
if (flags.task_isGroupChildTask()) {
545+
if (group) {
539546
auto groupChildFragment = task->groupChildFragment();
540547
new (groupChildFragment) AsyncTask::GroupChildFragment(group);
541548
}
@@ -597,6 +604,16 @@ static AsyncTaskAndContext swift_task_createImpl(
597604
initialContext->Flags = AsyncContextKind::Ordinary;
598605
initialContext->Flags.setShouldNotDeallocateInCallee(true);
599606

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+
600617
return {task, initialContext};
601618
}
602619

@@ -625,6 +642,18 @@ AsyncTaskAndContext swift::swift_task_create_future_f(
625642
function, initialContextSize);
626643
}
627644

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+
628657
AsyncTaskAndContext swift::swift_task_create_group_future_f(
629658
size_t flags,
630659
TaskGroup *group,
@@ -639,8 +668,8 @@ AsyncTaskAndContext swift::swift_task_create_group_future_f(
639668
}
640669

641670
return swift_task_create(
642-
flags, options, futureResultType, function, /*closureContext=*/nullptr,
643-
initialContextSize);
671+
convertJobFlagsToTaskCreateFlags(flags), options, futureResultType,
672+
function, /*closureContext=*/nullptr, initialContextSize);
644673
}
645674

646675
/// Extract the entry point address and initial context size from an async closure value.
@@ -674,8 +703,8 @@ AsyncTaskAndContext swift::swift_task_create_future(
674703
>(closureEntry, closureContext);
675704

676705
return swift_task_create(
677-
flags, options, futureResultType, taskEntry, closureContext,
678-
initialContextSize);
706+
convertJobFlagsToTaskCreateFlags(flags), options, futureResultType,
707+
taskEntry, closureContext, initialContextSize);
679708
}
680709

681710
AsyncTaskAndContext swift::swift_task_create_async_let_future(
@@ -694,8 +723,8 @@ AsyncTaskAndContext swift::swift_task_create_async_let_future(
694723
JobFlags flags(rawFlags);
695724
flags.task_setIsAsyncLetTask(true);
696725
return swift_task_create(
697-
flags.getOpaqueValue(), options, futureResultType,
698-
taskEntry, closureContext, initialContextSize);
726+
convertJobFlagsToTaskCreateFlags(flags.getOpaqueValue()), options,
727+
futureResultType, taskEntry, closureContext, initialContextSize);
699728
}
700729

701730
AsyncTaskAndContext
@@ -722,8 +751,8 @@ swift::swift_task_create_group_future(
722751
}
723752

724753
return swift_task_create(
725-
flags, options, futureResultType, taskEntry, closureContext,
726-
initialContextSize);
754+
convertJobFlagsToTaskCreateFlags(flags), options, futureResultType,
755+
taskEntry, closureContext, initialContextSize);
727756
}
728757

729758
SWIFT_CC(swiftasync)

0 commit comments

Comments
 (0)