|
| 1 | +//===--- Executor.h - ABI structures for executors --------------*- 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 executors. |
| 14 | +// |
| 15 | +//===----------------------------------------------------------------------===// |
| 16 | + |
| 17 | +#ifndef SWIFT_ABI_EXECUTOR_H |
| 18 | +#define SWIFT_ABI_EXECUTOR_H |
| 19 | + |
| 20 | +#include <inttypes.h> |
| 21 | + |
| 22 | +namespace swift { |
| 23 | +class AsyncContext; |
| 24 | +class AsyncTask; |
| 25 | +class DefaultActor; |
| 26 | +class Job; |
| 27 | + |
| 28 | +/// An ExecutorRef isn't necessarily just a pointer to an executor |
| 29 | +/// object; it may have other bits set. |
| 30 | +class ExecutorRef { |
| 31 | + static constexpr uintptr_t IsDefaultActor = 1; |
| 32 | + static constexpr uintptr_t PointerMask = 7; |
| 33 | + |
| 34 | + uintptr_t Value; |
| 35 | + |
| 36 | + constexpr ExecutorRef(uintptr_t value) : Value(value) {} |
| 37 | + |
| 38 | +public: |
| 39 | + /// A generic execution environment. When running in a generic |
| 40 | + /// environment, it's presumed to be okay to switch synchronously |
| 41 | + /// to an actor. As an executor request, this represents a request |
| 42 | + /// to drop whatever the current actor is. |
| 43 | + constexpr static ExecutorRef generic() { |
| 44 | + return ExecutorRef(0); |
| 45 | + } |
| 46 | + |
| 47 | + /// Given a pointer to a default actor, return an executor reference |
| 48 | + /// for it. |
| 49 | + static ExecutorRef forDefaultActor(DefaultActor *actor) { |
| 50 | + assert(actor); |
| 51 | + return ExecutorRef(reinterpret_cast<uintptr_t>(actor) | IsDefaultActor); |
| 52 | + } |
| 53 | + |
| 54 | + /// Is this the generic executor reference? |
| 55 | + bool isGeneric() const { |
| 56 | + return Value == 0; |
| 57 | + } |
| 58 | + |
| 59 | + /// Is this a default-actor executor reference? |
| 60 | + bool isDefaultActor() const { |
| 61 | + return Value & IsDefaultActor; |
| 62 | + } |
| 63 | + DefaultActor *getDefaultActor() const { |
| 64 | + assert(isDefaultActor()); |
| 65 | + return reinterpret_cast<DefaultActor*>(Value & ~PointerMask); |
| 66 | + } |
| 67 | + |
| 68 | + /// Do we have to do any work to start running as the requested |
| 69 | + /// executor? |
| 70 | + bool mustSwitchToRun(ExecutorRef newExecutor) const { |
| 71 | + return *this != newExecutor; |
| 72 | + } |
| 73 | + |
| 74 | + bool operator==(ExecutorRef other) const { |
| 75 | + return Value == other.Value; |
| 76 | + } |
| 77 | + bool operator!=(ExecutorRef other) const { |
| 78 | + return Value != other.Value; |
| 79 | + } |
| 80 | +}; |
| 81 | + |
| 82 | +using JobInvokeFunction = |
| 83 | + SWIFT_CC(swiftasync) |
| 84 | + void (Job *, ExecutorRef); |
| 85 | + |
| 86 | +using TaskContinuationFunction = |
| 87 | + SWIFT_CC(swiftasync) |
| 88 | + void (AsyncTask *, ExecutorRef, AsyncContext *); |
| 89 | + |
| 90 | +template <class Fn> |
| 91 | +struct AsyncFunctionTypeImpl; |
| 92 | +template <class Result, class... Params> |
| 93 | +struct AsyncFunctionTypeImpl<Result(Params...)> { |
| 94 | + // TODO: expand and include the arguments in the parameters. |
| 95 | + using type = TaskContinuationFunction; |
| 96 | +}; |
| 97 | + |
| 98 | +template <class Fn> |
| 99 | +using AsyncFunctionType = typename AsyncFunctionTypeImpl<Fn>::type; |
| 100 | + |
| 101 | +/// A "function pointer" for an async function. |
| 102 | +/// |
| 103 | +/// Eventually, this will always be signed with the data key |
| 104 | +/// using a type-specific discriminator. |
| 105 | +template <class FnType> |
| 106 | +class AsyncFunctionPointer { |
| 107 | +public: |
| 108 | + /// The function to run. |
| 109 | + RelativeDirectPointer<AsyncFunctionType<FnType>, |
| 110 | + /*nullable*/ false, |
| 111 | + int32_t> Function; |
| 112 | + |
| 113 | + /// The expected size of the context. |
| 114 | + uint32_t ExpectedContextSize; |
| 115 | +}; |
| 116 | + |
| 117 | +} |
| 118 | + |
| 119 | +#endif |
0 commit comments