Skip to content

Commit cce0600

Browse files
authored
Merge pull request #34997 from rjmccall/global-actor-dispatch
Back swift_task_enqueueGlobal with public Dispatch API
2 parents 58ff39b + 7cc63f9 commit cce0600

File tree

74 files changed

+1262
-251
lines changed

Some content is hidden

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

74 files changed

+1262
-251
lines changed

CMakeLists.txt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,10 +435,24 @@ option(SWIFT_BUILD_ONLY_SYNTAXPARSERLIB "Only build the Swift Syntax Parser libr
435435
option(SWIFT_BUILD_SOURCEKIT "Build SourceKit" TRUE)
436436
option(SWIFT_ENABLE_SOURCEKIT_TESTS "Enable running SourceKit tests" ${SWIFT_BUILD_SOURCEKIT})
437437

438+
# Use dispatch as the system scheduler by default.
439+
# For convenience, we set this to false when concurrency is disabled.
440+
set(SWIFT_CONCURRENCY_USES_DISPATCH FALSE)
441+
if(SWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY AND NOT SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
442+
set(SWIFT_CONCURRENCY_USES_DISPATCH TRUE)
443+
endif()
444+
445+
set(SWIFT_BUILD_HOST_DISPATCH FALSE)
438446
if(SWIFT_BUILD_SYNTAXPARSERLIB OR SWIFT_BUILD_SOURCEKIT)
447+
if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
448+
set(SWIFT_BUILD_HOST_DISPATCH TRUE)
449+
endif()
450+
endif()
451+
452+
if(SWIFT_BUILD_HOST_DISPATCH OR SWIFT_CONCURRENCY_USES_DISPATCH)
439453
if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
440454
if(NOT EXISTS "${SWIFT_PATH_TO_LIBDISPATCH_SOURCE}")
441-
message(SEND_ERROR "SyntaxParserLib and SourceKit require libdispatch on non-Darwin hosts. Please specify SWIFT_PATH_TO_LIBDISPATCH_SOURCE")
455+
message(SEND_ERROR "SyntaxParserLib, SourceKit, and concurrency require libdispatch on non-Darwin hosts. Please specify SWIFT_PATH_TO_LIBDISPATCH_SOURCE")
442456
endif()
443457
endif()
444458
endif()
@@ -941,7 +955,7 @@ if (LLVM_ENABLE_DOXYGEN)
941955
message(STATUS "Doxygen: enabled")
942956
endif()
943957

944-
if(SWIFT_BUILD_SYNTAXPARSERLIB OR SWIFT_BUILD_SOURCEKIT)
958+
if(SWIFT_BUILD_HOST_DISPATCH)
945959
if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
946960
if(CMAKE_C_COMPILER_ID STREQUAL Clang AND
947961
CMAKE_C_COMPILER_VERSION VERSION_GREATER 3.8

include/swift/ABI/Executor.h

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define SWIFT_ABI_EXECUTOR_H
1919

2020
#include <inttypes.h>
21+
#include "swift/ABI/HeapObject.h"
2122

2223
namespace swift {
2324
class AsyncContext;
@@ -65,6 +66,10 @@ class ExecutorRef {
6566
return reinterpret_cast<DefaultActor*>(Value & ~PointerMask);
6667
}
6768

69+
uintptr_t getRawValue() const {
70+
return Value;
71+
}
72+
6873
/// Do we have to do any work to start running as the requested
6974
/// executor?
7075
bool mustSwitchToRun(ExecutorRef newExecutor) const {
@@ -87,10 +92,53 @@ using TaskContinuationFunction =
8792
SWIFT_CC(swiftasync)
8893
void (AsyncTask *, ExecutorRef, AsyncContext *);
8994

90-
template <class Fn>
95+
template <class AsyncSignature>
96+
class AsyncFunctionPointer;
97+
template <class AsyncSignature>
9198
struct AsyncFunctionTypeImpl;
92-
template <class Result, class... Params>
93-
struct AsyncFunctionTypeImpl<Result(Params...)> {
99+
100+
/// The abstract signature for an asynchronous function.
101+
template <class Sig, bool HasErrorResult>
102+
struct AsyncSignature;
103+
104+
template <class DirectResultTy, class... ArgTys, bool HasErrorResult>
105+
struct AsyncSignature<DirectResultTy(ArgTys...), HasErrorResult> {
106+
bool hasDirectResult = !std::is_same<DirectResultTy, void>::value;
107+
using DirectResultType = DirectResultTy;
108+
109+
bool hasErrorResult = HasErrorResult;
110+
111+
using FunctionPointer = AsyncFunctionPointer<AsyncSignature>;
112+
using FunctionType = typename AsyncFunctionTypeImpl<AsyncSignature>::type;
113+
};
114+
115+
/// A signature for a thin async function that takes no arguments
116+
/// and returns no results.
117+
using ThinNullaryAsyncSignature =
118+
AsyncSignature<void(), false>;
119+
120+
/// A signature for a thick async function that takes no formal
121+
/// arguments and returns no results.
122+
using ThickNullaryAsyncSignature =
123+
AsyncSignature<void(HeapObject*), false>;
124+
125+
/// A class which can be used to statically query whether a type
126+
/// is a specialization of AsyncSignature.
127+
template <class T>
128+
struct IsAsyncSignature {
129+
static const bool value = false;
130+
};
131+
template <class DirectResultTy, class... ArgTys, bool HasErrorResult>
132+
struct IsAsyncSignature<AsyncSignature<DirectResultTy(ArgTys...),
133+
HasErrorResult>> {
134+
static const bool value = true;
135+
};
136+
137+
template <class Signature>
138+
struct AsyncFunctionTypeImpl {
139+
static_assert(IsAsyncSignature<Signature>::value,
140+
"template argument is not an AsyncSignature");
141+
94142
// TODO: expand and include the arguments in the parameters.
95143
using type = TaskContinuationFunction;
96144
};
@@ -102,11 +150,11 @@ using AsyncFunctionType = typename AsyncFunctionTypeImpl<Fn>::type;
102150
///
103151
/// Eventually, this will always be signed with the data key
104152
/// using a type-specific discriminator.
105-
template <class FnType>
153+
template <class AsyncSignature>
106154
class AsyncFunctionPointer {
107155
public:
108156
/// The function to run.
109-
RelativeDirectPointer<AsyncFunctionType<FnType>,
157+
RelativeDirectPointer<AsyncFunctionType<AsyncSignature>,
110158
/*nullable*/ false,
111159
int32_t> Function;
112160

include/swift/AST/ASTSynthesis.h

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
//===--- ASTSynthesis.h - Convenient Swift AST synthesis --------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 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+
#ifndef SWIFT_ASTSYNTHESIS_H
14+
#define SWIFT_ASTSYNTHESIS_H
15+
16+
#include "swift/AST/Types.h"
17+
#include "swift/AST/ASTContext.h"
18+
#include "swift/AST/Decl.h"
19+
#include "swift/AST/ParameterList.h"
20+
21+
namespace swift {
22+
23+
struct SynthesisContext {
24+
ASTContext &Context;
25+
DeclContext *DC;
26+
27+
SynthesisContext(ASTContext &ctx, DeclContext *DC)
28+
: Context(ctx), DC(DC) {}
29+
};
30+
31+
/// A synthesizer which generates a specific type.
32+
enum SingletonTypeSynthesizer {
33+
_void,
34+
_nativeObject,
35+
_job,
36+
};
37+
inline Type synthesizeType(SynthesisContext &SC,
38+
SingletonTypeSynthesizer kind) {
39+
switch (kind) {
40+
case _void: return SC.Context.TheEmptyTupleType;
41+
case _nativeObject: return SC.Context.TheNativeObjectType;
42+
case _job: return SC.Context.TheJobType;
43+
}
44+
}
45+
46+
/// Helper types for variadic synthesis.
47+
template <class... Ss>
48+
struct VariadicSynthesizerStorage;
49+
50+
template <>
51+
struct VariadicSynthesizerStorage<> {
52+
constexpr VariadicSynthesizerStorage() {}
53+
54+
template <class T, class Fn>
55+
void collect(SynthesisContext &SC, SmallVectorImpl<T> &results,
56+
Fn fn) const {}
57+
};
58+
template <class Head, class... Tail>
59+
struct VariadicSynthesizerStorage<Head, Tail...> {
60+
Head head;
61+
VariadicSynthesizerStorage<Tail...> tail;
62+
constexpr VariadicSynthesizerStorage(Head head, Tail... tail)
63+
: head(head), tail(tail...) {}
64+
65+
template <class T, class Fn>
66+
void collect(SynthesisContext &SC,
67+
SmallVectorImpl<T> &results,
68+
Fn fn) const {
69+
results.push_back(fn(SC, head));
70+
tail.collect(SC, results, fn);
71+
}
72+
};
73+
74+
/// Synthesize tuple type elements.
75+
template <class S>
76+
TupleTypeElt synthesizeTupleTypeElt(SynthesisContext &SC, S s) {
77+
return synthesizeType(SC, s);
78+
}
79+
struct SynthesizeTupleTypeElt {
80+
template <class S>
81+
TupleTypeElt operator()(SynthesisContext &SC, const S &s) {
82+
synthesizeTupleTypeElt(SC, s);
83+
}
84+
};
85+
86+
/// Synthesize tuple types.
87+
template <class... Elts>
88+
struct TupleSynthesizer {
89+
VariadicSynthesizerStorage<Elts...> Elements;
90+
};
91+
template <class... Elts>
92+
constexpr TupleSynthesizer<Elts...> _tuple(Elts... elts) {
93+
return {{elts...}};
94+
}
95+
template <class... Elts>
96+
Type synthesizeType(SynthesisContext &SC,
97+
const TupleSynthesizer<Elts...> &tuple) {
98+
SmallVector<TupleTypeElt, sizeof...(Elts)> elts;
99+
tuple.Elements.collect(SC, elts, SynthesizeTupleTypeElt());
100+
return TupleType::get(elts, SC.Context);
101+
}
102+
103+
/// Synthesize parameter declarations.
104+
template <class S>
105+
ParamDecl *synthesizeParamDecl(SynthesisContext &SC, const S &s) {
106+
auto type = synthesizeType(SC, s);
107+
auto PD = new (SC.Context) ParamDecl(SourceLoc(), SourceLoc(),
108+
Identifier(), SourceLoc(),
109+
Identifier(), SC.DC);
110+
PD->setInterfaceType(type);
111+
PD->setImplicit();
112+
return PD;
113+
}
114+
template <class S>
115+
FunctionType::Param synthesizeParamType(SynthesisContext &SC, const S &s) {
116+
auto type = synthesizeType(SC, s);
117+
return type;
118+
}
119+
120+
/// Parameter specifiers.
121+
template <class S>
122+
struct SpecifiedParamSynthesizer { ParamSpecifier specifier; S sub; };
123+
template <class G>
124+
constexpr SpecifiedParamSynthesizer<G> _owned(G sub) {
125+
return {ParamSpecifier::Owned, sub};
126+
}
127+
template <class G>
128+
constexpr SpecifiedParamSynthesizer<G> _inout(G sub) {
129+
return {ParamSpecifier::InOut, sub};
130+
}
131+
template <class S>
132+
ParamDecl *synthesizeParamDecl(SynthesisContext &SC,
133+
const SpecifiedParamSynthesizer<S> &s) {
134+
auto param = synthesizeParamDecl(SC, s.sub);
135+
param->setSpecifier(s.specifier);
136+
return param;
137+
}
138+
template <class S>
139+
FunctionType::Param synthesizeParamType(SynthesisContext &SC,
140+
const SpecifiedParamSynthesizer<S> &s) {
141+
auto param = synthesizeParamType(SC, s.sub);
142+
auto flags = param.getParameterFlags();
143+
if (s.specifier == ParamSpecifier::Owned)
144+
flags = flags.withOwned(true);
145+
if (s.specifier == ParamSpecifier::InOut)
146+
flags = flags.withInOut(true);
147+
return param.withFlags(flags);
148+
}
149+
150+
/// Synthesize a parameter list.
151+
template <class... Params>
152+
struct ParameterListSynthesizer {
153+
VariadicSynthesizerStorage<Params...> params;
154+
};
155+
template <class... Params>
156+
constexpr ParameterListSynthesizer<Params...> _parameters(Params... ps) {
157+
return {{ps...}};
158+
}
159+
160+
struct SynthesizeParamDecl {
161+
template <class S>
162+
ParamDecl *operator()(SynthesisContext &SC, const S &s) {
163+
// Found by argument-dependent lookup.
164+
return synthesizeParamDecl(SC, s);
165+
}
166+
};
167+
template <class... Params>
168+
ParameterList *synthesizeParameterList(SynthesisContext &SC,
169+
const ParameterListSynthesizer<Params...> &list) {
170+
SmallVector<ParamDecl*, 4> decls;
171+
list.params.collect(SC, decls, SynthesizeParamDecl());
172+
return ParameterList::create(SC.Context, decls);
173+
}
174+
175+
struct SynthesizeParamType {
176+
template <class S>
177+
FunctionType::Param operator()(SynthesisContext &SC, const S &s) {
178+
// Found by argument-dependent lookup.
179+
return synthesizeParamType(SC, s);
180+
}
181+
};
182+
template <class... Params>
183+
void synthesizeParameterTypes(SynthesisContext &SC,
184+
const ParameterListSynthesizer<Params...> &list,
185+
SmallVectorImpl<FunctionType::Param> &types) {
186+
list.params.collect(SC, types, SynthesizeParamType());
187+
}
188+
189+
/// Synthesize function ExtInfo.
190+
enum FunctionRepresentationSynthesizer {
191+
_thin,
192+
_thick
193+
};
194+
template <class S> struct ThrowsSynthesizer { S sub; };
195+
template <class S> struct AsyncSynthesizer { S sub; };
196+
template <class S>
197+
constexpr ThrowsSynthesizer<S> _throws(S sub) { return {sub}; }
198+
template <class S>
199+
constexpr AsyncSynthesizer<S> _async(S sub) { return {sub}; }
200+
201+
inline ASTExtInfo synthesizeExtInfo(SynthesisContext &SC,
202+
FunctionRepresentationSynthesizer kind) {
203+
switch (kind) {
204+
case _thin: return ASTExtInfo().withRepresentation(
205+
FunctionTypeRepresentation::Thin);
206+
case _thick: return ASTExtInfo().withRepresentation(
207+
FunctionTypeRepresentation::Swift);
208+
}
209+
}
210+
template <class S>
211+
ASTExtInfo synthesizeExtInfo(SynthesisContext &SC,
212+
const ThrowsSynthesizer<S> &s) {
213+
return synthesizeExtInfo(SC, s.sub).withThrows();
214+
}
215+
template <class S>
216+
ASTExtInfo synthesizeExtInfo(SynthesisContext &SC,
217+
const AsyncSynthesizer<S> &s) {
218+
return synthesizeExtInfo(SC, s.sub).withAsync();
219+
}
220+
221+
/// Synthesize a function type.
222+
template <class ExtInfoS, class ResultS, class ParamsS>
223+
struct FunctionTypeSynthesizer {
224+
ExtInfoS extInfo;
225+
ResultS result;
226+
ParamsS parameters;
227+
};
228+
template <class ExtInfoS, class ResultS, class ParamsS>
229+
FunctionTypeSynthesizer<ExtInfoS, ResultS, ParamsS>
230+
_function(ExtInfoS extInfo, ResultS result, ParamsS params) {
231+
return {extInfo, result, params};
232+
}
233+
template <class ExtInfoS, class ResultS, class ParamsS>
234+
Type synthesizeType(SynthesisContext &SC,
235+
const FunctionTypeSynthesizer<ExtInfoS, ResultS, ParamsS> &fn) {
236+
SmallVector<FunctionType::Param, 4> paramTypes;
237+
synthesizeParameterTypes(SC, fn.parameters, paramTypes);
238+
auto extInfo = synthesizeExtInfo(SC, fn.extInfo);
239+
auto resultType = synthesizeType(SC, fn.result);
240+
return FunctionType::get(paramTypes, resultType, extInfo);
241+
}
242+
243+
/// Synthesize optionals.
244+
template <class S>
245+
struct OptionalSynthesizer {
246+
S sub;
247+
};
248+
template <class S>
249+
constexpr OptionalSynthesizer<S> _optional(S sub) { return {sub}; }
250+
template <class S>
251+
Type synthesizeType(SynthesisContext &SC, const OptionalSynthesizer<S> &s) {
252+
return OptionalType::get(synthesizeType(SC, s.sub));
253+
}
254+
255+
} // end namespace swift
256+
257+
#endif

0 commit comments

Comments
 (0)