Skip to content

Back swift_task_enqueueGlobal with public Dispatch API #34997

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -435,10 +435,24 @@ option(SWIFT_BUILD_ONLY_SYNTAXPARSERLIB "Only build the Swift Syntax Parser libr
option(SWIFT_BUILD_SOURCEKIT "Build SourceKit" TRUE)
option(SWIFT_ENABLE_SOURCEKIT_TESTS "Enable running SourceKit tests" ${SWIFT_BUILD_SOURCEKIT})

# Use dispatch as the system scheduler by default.
# For convenience, we set this to false when concurrency is disabled.
set(SWIFT_CONCURRENCY_USES_DISPATCH FALSE)
if(SWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY AND NOT SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
set(SWIFT_CONCURRENCY_USES_DISPATCH TRUE)
endif()

set(SWIFT_BUILD_HOST_DISPATCH FALSE)
if(SWIFT_BUILD_SYNTAXPARSERLIB OR SWIFT_BUILD_SOURCEKIT)
if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
set(SWIFT_BUILD_HOST_DISPATCH TRUE)
endif()
endif()

if(SWIFT_BUILD_HOST_DISPATCH OR SWIFT_CONCURRENCY_USES_DISPATCH)
if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
if(NOT EXISTS "${SWIFT_PATH_TO_LIBDISPATCH_SOURCE}")
message(SEND_ERROR "SyntaxParserLib and SourceKit require libdispatch on non-Darwin hosts. Please specify SWIFT_PATH_TO_LIBDISPATCH_SOURCE")
message(SEND_ERROR "SyntaxParserLib, SourceKit, and concurrency require libdispatch on non-Darwin hosts. Please specify SWIFT_PATH_TO_LIBDISPATCH_SOURCE")
endif()
endif()
endif()
Expand Down Expand Up @@ -941,7 +955,7 @@ if (LLVM_ENABLE_DOXYGEN)
message(STATUS "Doxygen: enabled")
endif()

if(SWIFT_BUILD_SYNTAXPARSERLIB OR SWIFT_BUILD_SOURCEKIT)
if(SWIFT_BUILD_HOST_DISPATCH)
if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
if(CMAKE_C_COMPILER_ID STREQUAL Clang AND
CMAKE_C_COMPILER_VERSION VERSION_GREATER 3.8
Expand Down
58 changes: 53 additions & 5 deletions include/swift/ABI/Executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define SWIFT_ABI_EXECUTOR_H

#include <inttypes.h>
#include "swift/ABI/HeapObject.h"

namespace swift {
class AsyncContext;
Expand Down Expand Up @@ -65,6 +66,10 @@ class ExecutorRef {
return reinterpret_cast<DefaultActor*>(Value & ~PointerMask);
}

uintptr_t getRawValue() const {
return Value;
}

/// Do we have to do any work to start running as the requested
/// executor?
bool mustSwitchToRun(ExecutorRef newExecutor) const {
Expand All @@ -87,10 +92,53 @@ using TaskContinuationFunction =
SWIFT_CC(swiftasync)
void (AsyncTask *, ExecutorRef, AsyncContext *);

template <class Fn>
template <class AsyncSignature>
class AsyncFunctionPointer;
template <class AsyncSignature>
struct AsyncFunctionTypeImpl;
template <class Result, class... Params>
struct AsyncFunctionTypeImpl<Result(Params...)> {

/// The abstract signature for an asynchronous function.
template <class Sig, bool HasErrorResult>
struct AsyncSignature;

template <class DirectResultTy, class... ArgTys, bool HasErrorResult>
struct AsyncSignature<DirectResultTy(ArgTys...), HasErrorResult> {
bool hasDirectResult = !std::is_same<DirectResultTy, void>::value;
using DirectResultType = DirectResultTy;

bool hasErrorResult = HasErrorResult;

using FunctionPointer = AsyncFunctionPointer<AsyncSignature>;
using FunctionType = typename AsyncFunctionTypeImpl<AsyncSignature>::type;
};

/// A signature for a thin async function that takes no arguments
/// and returns no results.
using ThinNullaryAsyncSignature =
AsyncSignature<void(), false>;

/// A signature for a thick async function that takes no formal
/// arguments and returns no results.
using ThickNullaryAsyncSignature =
AsyncSignature<void(HeapObject*), false>;

/// A class which can be used to statically query whether a type
/// is a specialization of AsyncSignature.
template <class T>
struct IsAsyncSignature {
static const bool value = false;
};
template <class DirectResultTy, class... ArgTys, bool HasErrorResult>
struct IsAsyncSignature<AsyncSignature<DirectResultTy(ArgTys...),
HasErrorResult>> {
static const bool value = true;
};

template <class Signature>
struct AsyncFunctionTypeImpl {
static_assert(IsAsyncSignature<Signature>::value,
"template argument is not an AsyncSignature");

// TODO: expand and include the arguments in the parameters.
using type = TaskContinuationFunction;
};
Expand All @@ -102,11 +150,11 @@ using AsyncFunctionType = typename AsyncFunctionTypeImpl<Fn>::type;
///
/// Eventually, this will always be signed with the data key
/// using a type-specific discriminator.
template <class FnType>
template <class AsyncSignature>
class AsyncFunctionPointer {
public:
/// The function to run.
RelativeDirectPointer<AsyncFunctionType<FnType>,
RelativeDirectPointer<AsyncFunctionType<AsyncSignature>,
/*nullable*/ false,
int32_t> Function;

Expand Down
257 changes: 257 additions & 0 deletions include/swift/AST/ASTSynthesis.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
//===--- ASTSynthesis.h - Convenient Swift AST synthesis --------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_ASTSYNTHESIS_H
#define SWIFT_ASTSYNTHESIS_H

#include "swift/AST/Types.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
#include "swift/AST/ParameterList.h"

namespace swift {

struct SynthesisContext {
ASTContext &Context;
DeclContext *DC;

SynthesisContext(ASTContext &ctx, DeclContext *DC)
: Context(ctx), DC(DC) {}
};

/// A synthesizer which generates a specific type.
enum SingletonTypeSynthesizer {
_void,
_nativeObject,
_job,
};
inline Type synthesizeType(SynthesisContext &SC,
SingletonTypeSynthesizer kind) {
switch (kind) {
case _void: return SC.Context.TheEmptyTupleType;
case _nativeObject: return SC.Context.TheNativeObjectType;
case _job: return SC.Context.TheJobType;
}
}

/// Helper types for variadic synthesis.
template <class... Ss>
struct VariadicSynthesizerStorage;

template <>
struct VariadicSynthesizerStorage<> {
constexpr VariadicSynthesizerStorage() {}

template <class T, class Fn>
void collect(SynthesisContext &SC, SmallVectorImpl<T> &results,
Fn fn) const {}
};
template <class Head, class... Tail>
struct VariadicSynthesizerStorage<Head, Tail...> {
Head head;
VariadicSynthesizerStorage<Tail...> tail;
constexpr VariadicSynthesizerStorage(Head head, Tail... tail)
: head(head), tail(tail...) {}

template <class T, class Fn>
void collect(SynthesisContext &SC,
SmallVectorImpl<T> &results,
Fn fn) const {
results.push_back(fn(SC, head));
tail.collect(SC, results, fn);
}
};

/// Synthesize tuple type elements.
template <class S>
TupleTypeElt synthesizeTupleTypeElt(SynthesisContext &SC, S s) {
return synthesizeType(SC, s);
}
struct SynthesizeTupleTypeElt {
template <class S>
TupleTypeElt operator()(SynthesisContext &SC, const S &s) {
synthesizeTupleTypeElt(SC, s);
}
};

/// Synthesize tuple types.
template <class... Elts>
struct TupleSynthesizer {
VariadicSynthesizerStorage<Elts...> Elements;
};
template <class... Elts>
constexpr TupleSynthesizer<Elts...> _tuple(Elts... elts) {
return {{elts...}};
}
template <class... Elts>
Type synthesizeType(SynthesisContext &SC,
const TupleSynthesizer<Elts...> &tuple) {
SmallVector<TupleTypeElt, sizeof...(Elts)> elts;
tuple.Elements.collect(SC, elts, SynthesizeTupleTypeElt());
return TupleType::get(elts, SC.Context);
}

/// Synthesize parameter declarations.
template <class S>
ParamDecl *synthesizeParamDecl(SynthesisContext &SC, const S &s) {
auto type = synthesizeType(SC, s);
auto PD = new (SC.Context) ParamDecl(SourceLoc(), SourceLoc(),
Identifier(), SourceLoc(),
Identifier(), SC.DC);
PD->setInterfaceType(type);
PD->setImplicit();
return PD;
}
template <class S>
FunctionType::Param synthesizeParamType(SynthesisContext &SC, const S &s) {
auto type = synthesizeType(SC, s);
return type;
}

/// Parameter specifiers.
template <class S>
struct SpecifiedParamSynthesizer { ParamSpecifier specifier; S sub; };
template <class G>
constexpr SpecifiedParamSynthesizer<G> _owned(G sub) {
return {ParamSpecifier::Owned, sub};
}
template <class G>
constexpr SpecifiedParamSynthesizer<G> _inout(G sub) {
return {ParamSpecifier::InOut, sub};
}
template <class S>
ParamDecl *synthesizeParamDecl(SynthesisContext &SC,
const SpecifiedParamSynthesizer<S> &s) {
auto param = synthesizeParamDecl(SC, s.sub);
param->setSpecifier(s.specifier);
return param;
}
template <class S>
FunctionType::Param synthesizeParamType(SynthesisContext &SC,
const SpecifiedParamSynthesizer<S> &s) {
auto param = synthesizeParamType(SC, s.sub);
auto flags = param.getParameterFlags();
if (s.specifier == ParamSpecifier::Owned)
flags = flags.withOwned(true);
if (s.specifier == ParamSpecifier::InOut)
flags = flags.withInOut(true);
return param.withFlags(flags);
}

/// Synthesize a parameter list.
template <class... Params>
struct ParameterListSynthesizer {
VariadicSynthesizerStorage<Params...> params;
};
template <class... Params>
constexpr ParameterListSynthesizer<Params...> _parameters(Params... ps) {
return {{ps...}};
}

struct SynthesizeParamDecl {
template <class S>
ParamDecl *operator()(SynthesisContext &SC, const S &s) {
// Found by argument-dependent lookup.
return synthesizeParamDecl(SC, s);
}
};
template <class... Params>
ParameterList *synthesizeParameterList(SynthesisContext &SC,
const ParameterListSynthesizer<Params...> &list) {
SmallVector<ParamDecl*, 4> decls;
list.params.collect(SC, decls, SynthesizeParamDecl());
return ParameterList::create(SC.Context, decls);
}

struct SynthesizeParamType {
template <class S>
FunctionType::Param operator()(SynthesisContext &SC, const S &s) {
// Found by argument-dependent lookup.
return synthesizeParamType(SC, s);
}
};
template <class... Params>
void synthesizeParameterTypes(SynthesisContext &SC,
const ParameterListSynthesizer<Params...> &list,
SmallVectorImpl<FunctionType::Param> &types) {
list.params.collect(SC, types, SynthesizeParamType());
}

/// Synthesize function ExtInfo.
enum FunctionRepresentationSynthesizer {
_thin,
_thick
};
template <class S> struct ThrowsSynthesizer { S sub; };
template <class S> struct AsyncSynthesizer { S sub; };
template <class S>
constexpr ThrowsSynthesizer<S> _throws(S sub) { return {sub}; }
template <class S>
constexpr AsyncSynthesizer<S> _async(S sub) { return {sub}; }

inline ASTExtInfo synthesizeExtInfo(SynthesisContext &SC,
FunctionRepresentationSynthesizer kind) {
switch (kind) {
case _thin: return ASTExtInfo().withRepresentation(
FunctionTypeRepresentation::Thin);
case _thick: return ASTExtInfo().withRepresentation(
FunctionTypeRepresentation::Swift);
}
}
template <class S>
ASTExtInfo synthesizeExtInfo(SynthesisContext &SC,
const ThrowsSynthesizer<S> &s) {
return synthesizeExtInfo(SC, s.sub).withThrows();
}
template <class S>
ASTExtInfo synthesizeExtInfo(SynthesisContext &SC,
const AsyncSynthesizer<S> &s) {
return synthesizeExtInfo(SC, s.sub).withAsync();
}

/// Synthesize a function type.
template <class ExtInfoS, class ResultS, class ParamsS>
struct FunctionTypeSynthesizer {
ExtInfoS extInfo;
ResultS result;
ParamsS parameters;
};
template <class ExtInfoS, class ResultS, class ParamsS>
FunctionTypeSynthesizer<ExtInfoS, ResultS, ParamsS>
_function(ExtInfoS extInfo, ResultS result, ParamsS params) {
return {extInfo, result, params};
}
template <class ExtInfoS, class ResultS, class ParamsS>
Type synthesizeType(SynthesisContext &SC,
const FunctionTypeSynthesizer<ExtInfoS, ResultS, ParamsS> &fn) {
SmallVector<FunctionType::Param, 4> paramTypes;
synthesizeParameterTypes(SC, fn.parameters, paramTypes);
auto extInfo = synthesizeExtInfo(SC, fn.extInfo);
auto resultType = synthesizeType(SC, fn.result);
return FunctionType::get(paramTypes, resultType, extInfo);
}

/// Synthesize optionals.
template <class S>
struct OptionalSynthesizer {
S sub;
};
template <class S>
constexpr OptionalSynthesizer<S> _optional(S sub) { return {sub}; }
template <class S>
Type synthesizeType(SynthesisContext &SC, const OptionalSynthesizer<S> &s) {
return OptionalType::get(synthesizeType(SC, s.sub));
}

} // end namespace swift

#endif
Loading