Skip to content

Commit 799975a

Browse files
committed
[Concurrency] introduce task options, and change ABI to accept them
introduce new options parameter to all task spawning [Concurrency] ABI for asynclet start to accept options [Concurrency] fix unittest usages of changed task creation ABI [Concurrency] introduce constants for parameter indexes in ownership [Concurrency] fix test/SILOptimizer/closure_lifetime_fixup_concurrency.swift
1 parent 4934207 commit 799975a

37 files changed

+369
-159
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2101,6 +2101,12 @@ enum class TaskStatusRecordKind : uint8_t {
21012101
Private_RecordLock = 192
21022102
};
21032103

2104+
/// Kinds of option records that can be passed to creating asynchronous tasks.
2105+
enum class TaskOptionRecordKind : uint8_t {
2106+
/// Request a task to be kicked off, or resumed, on a specific executor.
2107+
Executor = 0,
2108+
};
2109+
21042110
/// Flags for cancellation records.
21052111
class TaskStatusRecordFlags : public FlagSet<size_t> {
21062112
public:
@@ -2119,6 +2125,24 @@ class TaskStatusRecordFlags : public FlagSet<size_t> {
21192125
getKind, setKind)
21202126
};
21212127

2128+
/// Flags for task option records.
2129+
class TaskOptionRecordFlags : public FlagSet<size_t> {
2130+
public:
2131+
enum {
2132+
Kind = 0,
2133+
Kind_width = 8,
2134+
};
2135+
2136+
explicit TaskOptionRecordFlags(size_t bits) : FlagSet(bits) {}
2137+
constexpr TaskOptionRecordFlags() {}
2138+
TaskOptionRecordFlags(TaskOptionRecordKind kind) {
2139+
setKind(kind);
2140+
}
2141+
2142+
FLAGSET_DEFINE_FIELD_ACCESSORS(Kind, Kind_width, TaskOptionRecordKind,
2143+
getKind, setKind)
2144+
};
2145+
21222146
/// Kinds of async context.
21232147
enum class AsyncContextKind {
21242148
/// 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: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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+
28+
namespace swift {
29+
30+
// ==== ------------------------------------------------------------------------
31+
// ==== Task Options, for creating and waiting on tasks
32+
33+
/// The abstract base class for all options that may be used
34+
/// to configure a newly spawned task.
35+
class TaskOptionRecord {
36+
public:
37+
TaskOptionRecordFlags Flags;
38+
TaskOptionRecord *Parent;
39+
40+
TaskOptionRecord(TaskOptionRecordKind kind,
41+
TaskOptionRecord *parent = nullptr)
42+
: Flags(kind) {
43+
Parent = parent;
44+
}
45+
46+
TaskOptionRecord(const TaskOptionRecord &) = delete;
47+
TaskOptionRecord &operator=(const TaskOptionRecord &) = delete;
48+
49+
TaskOptionRecordKind getKind() const {
50+
return Flags.getKind();
51+
}
52+
53+
TaskOptionRecord *getParent() const {
54+
return Parent;
55+
}
56+
57+
};
58+
59+
/// Task option to specify on what executor the task should be executed.
60+
///
61+
/// Not passing this option implies that that a "best guess" or good default
62+
/// executor should be used instead, most often this may mean the global
63+
/// concurrent executor, or the enclosing actor's executor.
64+
class ExecutorTaskOptionRecord : public TaskOptionRecord {
65+
ExecutorRef *Executor;
66+
67+
public:
68+
ExecutorTaskOptionRecord(ExecutorRef *executor)
69+
: TaskOptionRecord(TaskOptionRecordKind::Executor),
70+
Executor(executor) {}
71+
72+
ExecutorRef *getExecutor() const {
73+
return Executor;
74+
}
75+
};
76+
77+
} // end namespace swift
78+
79+
#endif

include/swift/AST/Builtins.def

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,9 @@ BUILTIN_MISC_OPERATION(StartAsyncLet, "startAsyncLet", "", Special)
795795
BUILTIN_MISC_OPERATION_WITH_SILGEN(EndAsyncLet, "endAsyncLet", "", Special)
796796

797797
/// createAsyncTaskFuture(): (
798-
/// Int, Builtin.NativeObject?, @escaping () async throws -> T
798+
/// Int, // flags
799+
/// Builtin.RawPointer?, // options (TaskOptionRecord*)
800+
/// @escaping () async throws -> T // function
799801
/// ) -> Builtin.NativeObject
800802
///
801803
/// Create a new asynchronous task future, given flags, an (optional) parent
@@ -804,10 +806,10 @@ BUILTIN_MISC_OPERATION_WITH_SILGEN(CreateAsyncTaskFuture,
804806
"createAsyncTaskFuture", "", Special)
805807

806808
/// createAsyncTaskGroupFuture(): (
807-
/// Int, // flags
808-
/// Builtin.NativeObject?, // parent
809-
/// Builtin.RawPointer?, // group
810-
/// @escaping () async throws -> T
809+
/// Int, // flags
810+
/// Builtin.RawPointer?, // group
811+
/// Builtin.RawPointer?, // options (TaskOptionRecord*)
812+
/// @escaping () async throws -> T // function
811813
/// ) -> Builtin.NativeObject
812814
///
813815
/// Create a new asynchronous task future, given flags, a parent task,

include/swift/Runtime/Concurrency.h

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
namespace swift {
2929
class DefaultActor;
30+
class TaskOptionRecord;
3031

3132
struct SwiftError;
3233

@@ -38,9 +39,10 @@ struct AsyncTaskAndContext {
3839
/// Create a task object with no future which will run the given
3940
/// function.
4041
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
41-
AsyncTaskAndContext swift_task_create_f(size_t flags,
42-
ThinNullaryAsyncSignature::FunctionType *function,
43-
size_t initialContextSize);
42+
AsyncTaskAndContext swift_task_create_f(
43+
size_t flags,
44+
TaskOptionRecord *options,
45+
ThinNullaryAsyncSignature::FunctionType *function, size_t initialContextSize);
4446

4547
/// Caution: not all future-initializing functions actually throw, so
4648
/// this signature may be incorrect.
@@ -52,37 +54,38 @@ using FutureAsyncSignature =
5254
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
5355
AsyncTaskAndContext swift_task_create_future(
5456
size_t flags,
57+
TaskOptionRecord *options,
5558
const Metadata *futureResultType,
56-
void *closureEntryPoint,
57-
HeapObject * /* +1 */ closureContext);
59+
void *closureEntryPoint, HeapObject * /* +1 */ closureContext);
5860

5961
/// Create a task object with a future which will run the given
6062
/// function.
6163
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
6264
AsyncTaskAndContext swift_task_create_future_f(
6365
size_t flags,
66+
TaskOptionRecord *options,
6467
const Metadata *futureResultType,
65-
FutureAsyncSignature::FunctionType *function,
66-
size_t initialContextSize);
68+
FutureAsyncSignature::FunctionType *function, size_t initialContextSize);
6769

6870
/// Create a task object with a future which will run the given
6971
/// closure, and offer its result to the task group
7072
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
7173
AsyncTaskAndContext swift_task_create_group_future(
72-
size_t flags, TaskGroup *group,
74+
size_t flags,
75+
TaskGroup *group,
76+
TaskOptionRecord *options,
7377
const Metadata *futureResultType,
74-
void *closureEntryPoint,
75-
HeapObject * /* +1 */ closureContext);
78+
void *closureEntryPoint, HeapObject * /* +1 */ closureContext);
7679

7780
/// Create a task object with a future which will run the given
7881
/// function, and offer its result to the task group
7982
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
8083
AsyncTaskAndContext swift_task_create_group_future_f(
8184
size_t flags,
8285
TaskGroup *group,
86+
TaskOptionRecord *options,
8387
const Metadata *futureResultType,
84-
FutureAsyncSignature::FunctionType *function,
85-
size_t initialContextSize);
88+
FutureAsyncSignature::FunctionType *function, size_t initialContextSize);
8689

8790
/// Allocate memory in a task.
8891
///
@@ -270,16 +273,16 @@ bool swift_taskGroup_isEmpty(TaskGroup *group);
270273
///
271274
/// \code
272275
/// func swift_asyncLet_start<T>(
273-
/// _ alet: Builtin.RawPointer,
276+
/// asyncLet: Builtin.RawPointer,
277+
/// options: Builtin.RawPointer?,
274278
/// operation: __owned @Sendable () async throws -> T
275279
/// )
276280
/// \endcode
277281
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
278-
void swift_asyncLet_start(
279-
AsyncLet *alet,
280-
const Metadata *futureResultType,
281-
void *closureEntryPoint,
282-
void *closureContext);
282+
void swift_asyncLet_start(AsyncLet *alet,
283+
TaskOptionRecord *options,
284+
const Metadata *futureResultType,
285+
void *closureEntryPoint, void *closureContext);
283286

284287
/// This matches the ABI of a closure `<T>(Builtin.RawPointer) async -> T`
285288
using AsyncLetWaitSignature =

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,69 +1549,84 @@ FUNCTION(TaskCancel,
15491549

15501550
// AsyncTaskAndContext swift_task_create_f(
15511551
// size_t flags,
1552-
// TaskContinuationFunction* function,
1553-
// size_t contextSize);
1552+
// TaskOptionRecord *options,
1553+
// TaskContinuationFunction* function, size_t contextSize);
15541554
FUNCTION(TaskCreateFunc,
15551555
swift_task_create_f, SwiftCC,
15561556
ConcurrencyAvailability,
15571557
RETURNS(AsyncTaskAndContextTy),
1558-
ARGS(SizeTy, TaskContinuationFunctionPtrTy, SizeTy),
1558+
ARGS(SizeTy,
1559+
SwiftTaskOptionRecordPtrTy,
1560+
TaskContinuationFunctionPtrTy,
1561+
SizeTy),
15591562
ATTRS(NoUnwind, ArgMemOnly))
15601563

15611564
// AsyncTaskAndContext swift_task_create_future(
15621565
// size_t flags,
1566+
// TaskOptionRecord *options,
15631567
// const Metadata *futureResultType,
1564-
// void *closureEntry,
1565-
// HeapObject *closureContext);
1568+
// void *closureEntry, HeapObject *closureContext);
15661569
FUNCTION(TaskCreateFuture,
15671570
swift_task_create_future, SwiftCC,
15681571
ConcurrencyAvailability,
15691572
RETURNS(AsyncTaskAndContextTy),
1570-
ARGS(SizeTy, TypeMetadataPtrTy,
1571-
Int8PtrTy, RefCountedPtrTy),
1573+
ARGS(SizeTy,
1574+
SwiftTaskOptionRecordPtrTy,
1575+
TypeMetadataPtrTy,
1576+
Int8PtrTy,
1577+
RefCountedPtrTy),
15721578
ATTRS(NoUnwind, ArgMemOnly))
15731579

15741580
// AsyncTaskAndContext swift_task_create_future_f(
15751581
// size_t flags,
1582+
// TaskOptionRecord *options,
15761583
// const Metadata *futureResultType,
1577-
// TaskContinuationFunction *function,
1578-
// size_t contextSize);
1584+
// TaskContinuationFunction *function, size_t contextSize);
15791585
FUNCTION(TaskCreateFutureFunc,
15801586
swift_task_create_future_f, SwiftCC,
15811587
ConcurrencyAvailability,
15821588
RETURNS(AsyncTaskAndContextTy),
1583-
ARGS(SizeTy, TypeMetadataPtrTy,
1584-
TaskContinuationFunctionPtrTy, SizeTy),
1589+
ARGS(SizeTy,
1590+
SwiftTaskOptionRecordPtrTy,
1591+
TypeMetadataPtrTy,
1592+
TaskContinuationFunctionPtrTy,
1593+
SizeTy),
15851594
ATTRS(NoUnwind, ArgMemOnly))
15861595

15871596
// AsyncTaskAndContext swift_task_create_group_future(
15881597
// size_t flags,
15891598
// TaskGroup *group,
1599+
// TaskOptionRecord *options
15901600
// const Metadata *futureResultType,
1591-
// void *closureEntry,
1592-
// HeapObject *closureContext);
1601+
// void *closureEntry, HeapObject *closureContext);
15931602
FUNCTION(TaskCreateGroupFuture,
15941603
swift_task_create_group_future, SwiftCC,
15951604
ConcurrencyAvailability,
15961605
RETURNS(AsyncTaskAndContextTy),
1597-
ARGS(SizeTy, SwiftTaskGroupPtrTy,
1606+
ARGS(SizeTy,
1607+
SwiftTaskGroupPtrTy,
1608+
SwiftTaskOptionRecordPtrTy,
15981609
TypeMetadataPtrTy,
1599-
Int8PtrTy, RefCountedPtrTy),
1610+
Int8PtrTy,
1611+
RefCountedPtrTy),
16001612
ATTRS(NoUnwind, ArgMemOnly))
16011613

16021614
// AsyncTaskAndContext swift_task_create_group_future_f(
16031615
// size_t flags,
16041616
// TaskGroup *group,
1617+
// TaskOptionRecord *options
16051618
// const Metadata *futureResultType,
1606-
// TaskContinuationFunction *function,
1607-
// size_t contextSize);
1619+
// TaskContinuationFunction *function, size_t contextSize);
16081620
FUNCTION(TaskCreateGroupFutureFunc,
16091621
swift_task_create_group_future_f, SwiftCC,
16101622
ConcurrencyAvailability,
16111623
RETURNS(AsyncTaskAndContextTy),
1612-
ARGS(SizeTy, SwiftTaskGroupPtrTy,
1624+
ARGS(SizeTy,
1625+
SwiftTaskGroupPtrTy,
1626+
SwiftTaskOptionRecordPtrTy,
16131627
TypeMetadataPtrTy,
1614-
TaskContinuationFunctionPtrTy, SizeTy),
1628+
TaskContinuationFunctionPtrTy,
1629+
SizeTy),
16151630
ATTRS(NoUnwind, ArgMemOnly))
16161631

16171632
// void swift_task_switch(AsyncContext *resumeContext,
@@ -1708,6 +1723,7 @@ FUNCTION(DefaultActorDeallocateResilient,
17081723

17091724
/// void swift_asyncLet_start(
17101725
/// AsyncLet *alet,
1726+
/// TaskOptionRecord *options,
17111727
/// const Metadata *futureResultType,
17121728
/// void *closureEntryPoint,
17131729
/// OpaqueValue *closureContext
@@ -1716,10 +1732,11 @@ FUNCTION(AsyncLetStart,
17161732
swift_asyncLet_start, SwiftCC,
17171733
ConcurrencyAvailability,
17181734
RETURNS(VoidTy),
1719-
ARGS(SwiftAsyncLetPtrTy, // AsyncLet*, alias for Int8PtrTy
1720-
TypeMetadataPtrTy, // futureResultType
1721-
Int8PtrTy, // closureEntry
1722-
OpaquePtrTy, // closureContext
1735+
ARGS(SwiftAsyncLetPtrTy, // AsyncLet*
1736+
SwiftTaskOptionRecordPtrTy, // options
1737+
TypeMetadataPtrTy, // futureResultType
1738+
Int8PtrTy, // closureEntry
1739+
OpaquePtrTy, // closureContext
17231740
),
17241741
ATTRS(NoUnwind, ArgMemOnly))
17251742

0 commit comments

Comments
 (0)