Skip to content

Commit 847e3f7

Browse files
authored
Merge pull request #38076 from DougGregor/centralize-task-creation-5.5
Centralize task creation in the Concurrency runtime
2 parents cd53207 + 2673285 commit 847e3f7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+714
-579
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2022,6 +2022,43 @@ 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+
// bit 9 is unused
2034+
Task_CopyTaskLocals = 10,
2035+
Task_InheritContext = 11,
2036+
Task_EnqueueJob = 12,
2037+
Task_AddPendingGroupTaskUnconditionally = 13,
2038+
};
2039+
2040+
explicit constexpr TaskCreateFlags(size_t bits) : FlagSet(bits) {}
2041+
constexpr TaskCreateFlags() {}
2042+
2043+
FLAGSET_DEFINE_FIELD_ACCESSORS(Priority, Priority_width, JobPriority,
2044+
getPriority, setPriority)
2045+
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsChildTask,
2046+
isChildTask,
2047+
setIsChildTask)
2048+
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_CopyTaskLocals,
2049+
copyTaskLocals,
2050+
setCopyTaskLocals)
2051+
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_InheritContext,
2052+
inheritContext,
2053+
setInheritContext)
2054+
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_EnqueueJob,
2055+
enqueueJob,
2056+
setEnqueueJob)
2057+
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_AddPendingGroupTaskUnconditionally,
2058+
addPendingGroupTaskUnconditionally,
2059+
setAddPendingGroupTaskUnconditionally)
2060+
};
2061+
20252062
/// Flags for schedulable jobs.
20262063
class JobFlags : public FlagSet<uint32_t> {
20272064
public:
@@ -2036,10 +2073,11 @@ class JobFlags : public FlagSet<uint32_t> {
20362073

20372074
// Kind-specific flags.
20382075

2039-
Task_IsChildTask = 24,
2040-
Task_IsFuture = 25,
2041-
Task_IsGroupChildTask = 26,
2042-
Task_IsContinuingAsyncTask = 27,
2076+
Task_IsChildTask = 24,
2077+
Task_IsFuture = 25,
2078+
Task_IsGroupChildTask = 26,
2079+
// 27 is currently unused
2080+
Task_IsAsyncLetTask = 28,
20432081
};
20442082

20452083
explicit JobFlags(uint32_t bits) : FlagSet(bits) {}
@@ -2069,9 +2107,9 @@ class JobFlags : public FlagSet<uint32_t> {
20692107
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsGroupChildTask,
20702108
task_isGroupChildTask,
20712109
task_setIsGroupChildTask)
2072-
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsContinuingAsyncTask,
2073-
task_isContinuingAsyncTask,
2074-
task_setIsContinuingAsyncTask)
2110+
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsAsyncLetTask,
2111+
task_isAsyncLetTask,
2112+
task_setIsAsyncLetTask)
20752113
};
20762114

20772115
/// Kinds of task status record.
@@ -2101,6 +2139,16 @@ enum class TaskStatusRecordKind : uint8_t {
21012139
Private_RecordLock = 192
21022140
};
21032141

2142+
/// Kinds of option records that can be passed to creating asynchronous tasks.
2143+
enum class TaskOptionRecordKind : uint8_t {
2144+
/// Request a task to be kicked off, or resumed, on a specific executor.
2145+
Executor = 0,
2146+
/// Request a child task to be part of a specific task group.
2147+
TaskGroup = 1,
2148+
/// Request a child task for an 'async let'.
2149+
AsyncLet = 2,
2150+
};
2151+
21042152
/// Flags for cancellation records.
21052153
class TaskStatusRecordFlags : public FlagSet<size_t> {
21062154
public:
@@ -2119,6 +2167,24 @@ class TaskStatusRecordFlags : public FlagSet<size_t> {
21192167
getKind, setKind)
21202168
};
21212169

2170+
/// Flags for task option records.
2171+
class TaskOptionRecordFlags : public FlagSet<size_t> {
2172+
public:
2173+
enum {
2174+
Kind = 0,
2175+
Kind_width = 8,
2176+
};
2177+
2178+
explicit TaskOptionRecordFlags(size_t bits) : FlagSet(bits) {}
2179+
constexpr TaskOptionRecordFlags() {}
2180+
TaskOptionRecordFlags(TaskOptionRecordKind kind) {
2181+
setKind(kind);
2182+
}
2183+
2184+
FLAGSET_DEFINE_FIELD_ACCESSORS(Kind, Kind_width, TaskOptionRecordKind,
2185+
getKind, setKind)
2186+
};
2187+
21222188
/// Kinds of async context.
21232189
enum class AsyncContextKind {
21242190
/// An ordinary asynchronous function.

include/swift/ABI/Task.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class Job;
3434
struct OpaqueValue;
3535
struct SwiftError;
3636
class TaskStatusRecord;
37+
class TaskOptionRecord;
3738
class TaskGroup;
3839

3940
extern FullMetadata<DispatchClassMetadata> jobHeapMetadata;
@@ -537,6 +538,8 @@ inline void Job::runInFullyEstablishedContext() {
537538
return runSimpleInFullyEstablishedContext(); // 'return' forces tail call
538539
}
539540

541+
// ==== ------------------------------------------------------------------------
542+
540543
/// An asynchronous context within a task. Generally contexts are
541544
/// allocated using the task-local stack alloc/dealloc operations, but
542545
/// there's no guarantee of that, and the ABI is designed to permit

include/swift/ABI/TaskLocal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
//
13-
// Swift ABI describing tasks.
13+
// Swift ABI describing task locals.
1414
//
1515
//===----------------------------------------------------------------------===//
1616

include/swift/ABI/TaskOptions.h

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
//===--- TaskOptions.h - ABI structures for task options --------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Swift ABI describing task options.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_ABI_TASK_OPTIONS_H
18+
#define SWIFT_ABI_TASK_OPTIONS_H
19+
20+
#include "swift/ABI/TaskLocal.h"
21+
#include "swift/ABI/Executor.h"
22+
#include "swift/ABI/HeapObject.h"
23+
#include "swift/ABI/Metadata.h"
24+
#include "swift/ABI/MetadataValues.h"
25+
#include "swift/Runtime/Config.h"
26+
#include "swift/Basic/STLExtras.h"
27+
#include "llvm/Support/Casting.h"
28+
29+
namespace swift {
30+
31+
// ==== ------------------------------------------------------------------------
32+
// ==== Task Options, for creating and waiting on tasks
33+
34+
/// The abstract base class for all options that may be used
35+
/// to configure a newly spawned task.
36+
class TaskOptionRecord {
37+
public:
38+
const TaskOptionRecordFlags Flags;
39+
TaskOptionRecord *Parent;
40+
41+
TaskOptionRecord(TaskOptionRecordKind kind,
42+
TaskOptionRecord *parent = nullptr)
43+
: Flags(kind), Parent(parent) { }
44+
45+
TaskOptionRecord(const TaskOptionRecord &) = delete;
46+
TaskOptionRecord &operator=(const TaskOptionRecord &) = delete;
47+
48+
TaskOptionRecordKind getKind() const {
49+
return Flags.getKind();
50+
}
51+
52+
TaskOptionRecord *getParent() const {
53+
return Parent;
54+
}
55+
};
56+
57+
/******************************************************************************/
58+
/****************************** TASK OPTIONS **********************************/
59+
/******************************************************************************/
60+
61+
class TaskGroupTaskOptionRecord : public TaskOptionRecord {
62+
TaskGroup * const Group;
63+
64+
public:
65+
TaskGroupTaskOptionRecord(TaskGroup *group)
66+
: TaskOptionRecord(TaskOptionRecordKind::TaskGroup),
67+
Group(group) {}
68+
69+
TaskGroup *getGroup() const {
70+
return Group;
71+
}
72+
73+
static bool classof(const TaskOptionRecord *record) {
74+
return record->getKind() == TaskOptionRecordKind::TaskGroup;
75+
}
76+
};
77+
78+
79+
/// Task option to specify on what executor the task should be executed.
80+
///
81+
/// Not passing this option implies that that a "best guess" or good default
82+
/// executor should be used instead, most often this may mean the global
83+
/// concurrent executor, or the enclosing actor's executor.
84+
class ExecutorTaskOptionRecord : public TaskOptionRecord {
85+
const ExecutorRef Executor;
86+
87+
public:
88+
ExecutorTaskOptionRecord(ExecutorRef executor)
89+
: TaskOptionRecord(TaskOptionRecordKind::Executor),
90+
Executor(executor) {}
91+
92+
ExecutorRef getExecutor() const {
93+
return Executor;
94+
}
95+
96+
static bool classof(const TaskOptionRecord *record) {
97+
return record->getKind() == TaskOptionRecordKind::Executor;
98+
}
99+
};
100+
101+
/// Task option to specify that the created task is for an 'async let'.
102+
class AsyncLetTaskOptionRecord : public TaskOptionRecord {
103+
AsyncLet *asyncLet;
104+
105+
public:
106+
AsyncLetTaskOptionRecord(AsyncLet *asyncLet)
107+
: TaskOptionRecord(TaskOptionRecordKind::AsyncLet),
108+
asyncLet(asyncLet) {}
109+
110+
AsyncLet *getAsyncLet() const {
111+
return asyncLet;
112+
}
113+
114+
static bool classof(const TaskOptionRecord *record) {
115+
return record->getKind() == TaskOptionRecordKind::AsyncLet;
116+
}
117+
};
118+
119+
} // end namespace swift
120+
121+
#endif

include/swift/AST/Builtins.def

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -794,26 +794,26 @@ BUILTIN_MISC_OPERATION(StartAsyncLet, "startAsyncLet", "", Special)
794794
/// until the endAsyncLet.
795795
BUILTIN_MISC_OPERATION_WITH_SILGEN(EndAsyncLet, "endAsyncLet", "", Special)
796796

797-
/// createAsyncTaskFuture(): (
798-
/// Int, Builtin.NativeObject?, @escaping () async throws -> T
797+
/// createAsyncTask(): (
798+
/// Int, // task-creation flags
799+
/// @escaping () async throws -> T // function
799800
/// ) -> Builtin.NativeObject
800801
///
801-
/// Create a new asynchronous task future, given flags, an (optional) parent
802-
/// task and a function to execute.
803-
BUILTIN_MISC_OPERATION_WITH_SILGEN(CreateAsyncTaskFuture,
804-
"createAsyncTaskFuture", "", Special)
802+
/// Create a new asynchronous task, given flags, options, and a function to
803+
/// execute.
804+
BUILTIN_MISC_OPERATION_WITH_SILGEN(CreateAsyncTask,
805+
"createAsyncTask", "", Special)
805806

806-
/// createAsyncTaskGroupFuture(): (
807-
/// Int, // flags
808-
/// Builtin.NativeObject?, // parent
809-
/// Builtin.RawPointer?, // group
810-
/// @escaping () async throws -> T
807+
/// createAsyncTaskInGroup(): (
808+
/// Int, // flags
809+
/// Builtin.RawPointer, // group
810+
/// @escaping () async throws -> T // function
811811
/// ) -> Builtin.NativeObject
812812
///
813813
/// Create a new asynchronous task future, given flags, a parent task,
814814
/// task group and a function to execute.
815-
BUILTIN_MISC_OPERATION_WITH_SILGEN(CreateAsyncTaskGroupFuture,
816-
"createAsyncTaskGroupFuture", "", Special)
815+
BUILTIN_MISC_OPERATION_WITH_SILGEN(CreateAsyncTaskInGroup,
816+
"createAsyncTaskInGroup", "", Special)
817817

818818
/// globalStringTablePointer has type String -> Builtin.RawPointer.
819819
/// It returns an immortal, global string table pointer for strings constructed

include/swift/Basic/Features.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,6 @@ LANGUAGE_FEATURE(InheritActorContext, 0, "@_inheritActorContext attribute", true
5252
LANGUAGE_FEATURE(ImplicitSelfCapture, 0, "@_implicitSelfCapture attribute", true)
5353
LANGUAGE_FEATURE(BuiltinBuildExecutor, 0, "Executor-building builtins", true)
5454
LANGUAGE_FEATURE(BuiltinBuildMainExecutor, 0, "MainActor executor building builtin", true)
55+
LANGUAGE_FEATURE(BuiltinCreateAsyncTaskInGroup, 0, "MainActor executor building builtin", true)
5556

5657
#undef LANGUAGE_FEATURE

0 commit comments

Comments
 (0)