Skip to content

Commit 14dcab6

Browse files
committed
Restore (TaskOptionRecordKind)0 to set the initial serial executor.
This has been the behavior of the runtime since the initial release. Initially, it was thought that task executors would provide similar functionality, so they naturally took over the enumerator. After that changed, we forgot to change it back. Fortunately, we haven't released any versions of Swift with the task executors feature yet, so it's not too late to fix this.
1 parent 24c3528 commit 14dcab6

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2614,8 +2614,10 @@ enum class TaskStatusRecordKind : uint8_t {
26142614

26152615
/// Kinds of option records that can be passed to creating asynchronous tasks.
26162616
enum class TaskOptionRecordKind : uint8_t {
2617-
/// Request a task to be kicked off, or resumed, on a specific executor.
2618-
InitialTaskExecutor = 0,
2617+
/// Request a task to start running on a specific serial executor.
2618+
/// This was renamed in 6.0 to disambiguate with task executors, but the
2619+
/// support was in the runtime from the first release.
2620+
InitialSerialExecutor = 0,
26192621
/// Request a child task to be part of a specific task group.
26202622
TaskGroup = 1,
26212623
/// DEPRECATED. AsyncLetWithBuffer is used instead.
@@ -2625,6 +2627,8 @@ enum class TaskOptionRecordKind : uint8_t {
26252627
AsyncLetWithBuffer = 3,
26262628
/// Information about the result type of the task, used in embedded Swift.
26272629
ResultTypeInfo = 4,
2630+
/// Set the initial task executor preference of the task.
2631+
InitialTaskExecutor = 5,
26282632
/// Request a child task for swift_task_run_inline.
26292633
RunInline = UINT8_MAX,
26302634
};

include/swift/ABI/TaskOptions.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,21 @@ class InitialTaskExecutorPreferenceTaskOptionRecord : public TaskOptionRecord {
9797
}
9898
};
9999

100+
/// Task option to specify the initial serial executor for the task.
101+
class InitialSerialExecutorTaskOptionRecord : public TaskOptionRecord {
102+
const SerialExecutorRef Executor;
103+
public:
104+
InitialSerialExecutorTaskOptionRecord(SerialExecutorRef executor)
105+
: TaskOptionRecord(TaskOptionRecordKind::InitialSerialExecutor),
106+
Executor(executor) {}
107+
108+
SerialExecutorRef getExecutorRef() const { return Executor; }
109+
110+
static bool classof(const TaskOptionRecord *record) {
111+
return record->getKind() == TaskOptionRecordKind::InitialSerialExecutor;
112+
}
113+
};
114+
100115
/// DEPRECATED. AsyncLetWithBufferTaskOptionRecord is used instead.
101116
/// Task option to specify that the created task is for an 'async let'.
102117
class AsyncLetTaskOptionRecord : public TaskOptionRecord {

stdlib/public/Concurrency/Task.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,11 @@ swift_task_create_commonImpl(size_t rawTaskCreateFlags,
653653
RunInlineTaskOptionRecord *runInlineOption = nullptr;
654654
for (auto option = options; option; option = option->getParent()) {
655655
switch (option->getKind()) {
656+
case TaskOptionRecordKind::InitialSerialExecutor:
657+
serialExecutor = cast<InitialSerialExecutorTaskOptionRecord>(option)
658+
->getExecutorRef();
659+
break;
660+
656661
case TaskOptionRecordKind::InitialTaskExecutor:
657662
taskExecutor = cast<InitialTaskExecutorPreferenceTaskOptionRecord>(option)
658663
->getExecutorRef();

test/IRGen/async/builtins.sil

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,32 @@ sil hidden @launch_discarding_future_in_group_with_executor : $@convention(thin)
112112
bb0(%taskGroup : $Builtin.RawPointer, %taskExecutor : $Builtin.Executor, %taskFunction : $@Sendable @async @callee_guaranteed () -> @error Error, %flags: $Int):
113113
%optTaskGroup = enum $Optional<Builtin.RawPointer>, #Optional.some!enumelt, %taskGroup : $Builtin.RawPointer
114114
%optTaskExecutor = enum $Optional<Builtin.Executor>, #Optional.some!enumelt, %taskExecutor : $Builtin.Executor
115+
// CHECK: [[GROUP_RECORD:%.*]] = alloca %swift.task_group_task_option
116+
// CHECK: [[EXECUTOR_RECORD:%.*]] = alloca %swift.task_executor_task_option
115117
// CHECK-NOT: br i1
116-
// CHECK: call swift{{(tail)?}}cc %swift.async_task_and_context @swift_task_create(
118+
119+
// CHECK: [[BASE_GEP:%.*]] = getelementptr inbounds %swift.task_group_task_option, ptr [[GROUP_RECORD]], i32 0, i32 0
120+
// CHECK: [[FLAGS_GEP:%.*]] = getelementptr inbounds %swift.task_option, ptr [[BASE_GEP]], i32 0, i32 0
121+
// CHECK: store [[INT]] 1, ptr [[FLAGS_GEP]], align
122+
// CHECK: [[PARENT_GEP:%.*]] = getelementptr inbounds %swift.task_option, ptr [[BASE_GEP]], i32 0, i32 1
123+
// CHECK: store [[INT]] 0, ptr [[PARENT_GEP]], align
124+
// CHECK: [[GROUP_GEP:%.*]] = getelementptr inbounds %swift.task_group_task_option, ptr [[GROUP_RECORD]], i32 0, i32 1
125+
// CHECK: store ptr %0, ptr [[GROUP_GEP]], align
126+
// CHECK: [[OPTIONS_PTR:%.*]] = ptrtoint ptr [[GROUP_RECORD]] to [[INT]]
127+
128+
// CHECK: [[BASE_GEP:%.*]] = getelementptr inbounds %swift.task_executor_task_option, ptr [[EXECUTOR_RECORD]], i32 0, i32 0
129+
// CHECK: [[FLAGS_GEP:%.*]] = getelementptr inbounds %swift.task_option, ptr [[BASE_GEP]], i32 0, i32 0
130+
// CHECK: store [[INT]] 5, ptr [[FLAGS_GEP]], align
131+
// CHECK: [[PARENT_GEP:%.*]] = getelementptr inbounds %swift.task_option, ptr [[BASE_GEP]], i32 0, i32 1
132+
// CHECK: store [[INT]] [[OPTIONS_PTR]], ptr [[PARENT_GEP]], align
133+
// CHECK: [[EXECUTOR_GEP:%.*]] = getelementptr inbounds %swift.task_executor_task_option, ptr [[EXECUTOR_RECORD]], i32 0, i32 1
134+
// CHECK: [[EXECUTOR_IDENT_GEP:%.*]] = getelementptr inbounds %swift.executor, ptr [[EXECUTOR_GEP]], i32 0, i32 0
135+
// CHECK: store [[INT]] %1, ptr [[EXECUTOR_IDENT_GEP]], align
136+
// CHECK: [[EXECUTOR_IMPL_GEP:%.*]] = getelementptr inbounds %swift.executor, ptr [[EXECUTOR_GEP]], i32 0, i32 1
137+
// CHECK: store [[INT]] %2, ptr [[EXECUTOR_IMPL_GEP]], align
138+
// CHECK: [[OPTIONS_PTR:%.*]] = ptrtoint ptr [[EXECUTOR_RECORD]] to [[INT]]
139+
140+
// CHECK: call swift{{(tail)?}}cc %swift.async_task_and_context @swift_task_create([[INT]] %5, [[INT]] [[OPTIONS_PTR]]
117141
%9 = builtin "createAsyncTask"(%flags : $Int, %optTaskGroup : $Optional<Builtin.RawPointer>, %optTaskExecutor: $Optional<Builtin.Executor>, %taskFunction : $@Sendable @async @callee_guaranteed () -> @error Error) : $(Builtin.NativeObject, Builtin.RawPointer)
118142
%10 = tuple_extract %9 : $(Builtin.NativeObject, Builtin.RawPointer), 0
119143
strong_release %10 : $Builtin.NativeObject

0 commit comments

Comments
 (0)