Skip to content

Commit 624b272

Browse files
committed
[Distributed] Move some of the swift_distributed_* accessors to a dedicated file
Add a new `DistributedActor.cpp` and move some of the logic related to swift_distributed_execute_target there to avoid exporting it from Concurrency.
1 parent 4cfd1d0 commit 624b272

File tree

4 files changed

+161
-137
lines changed

4 files changed

+161
-137
lines changed

stdlib/public/Concurrency/Actor.cpp

Lines changed: 0 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1698,139 +1698,3 @@ bool DefaultActorImpl::isDistributedRemote() {
16981698
auto state = CurrentState.load(std::memory_order_relaxed);
16991699
return state.Flags.isDistributedRemote();
17001700
}
1701-
1702-
static const AccessibleFunctionRecord *
1703-
findDistributedAccessor(const char *targetNameStart, size_t targetNameLength) {
1704-
if (auto *func = runtime::swift_findAccessibleFunction(targetNameStart,
1705-
targetNameLength)) {
1706-
assert(func->Flags.isDistributed());
1707-
return func;
1708-
}
1709-
return nullptr;
1710-
}
1711-
1712-
SWIFT_CC(swift)
1713-
SWIFT_RUNTIME_STDLIB_SPI
1714-
void *swift_distributed_get_generic_environment(const char *targetNameStart,
1715-
size_t targetNameLength) {
1716-
auto *accessor = findDistributedAccessor(targetNameStart, targetNameLength);
1717-
return accessor ? accessor->GenericEnvironment.get() : nullptr;
1718-
}
1719-
1720-
/// func _executeDistributedTarget(
1721-
/// on: AnyObject,
1722-
/// _ targetName: UnsafePointer<UInt8>,
1723-
/// _ targetNameLength: UInt,
1724-
/// argumentBuffer: Builtin.RawPointer,
1725-
/// argumentTypes: UnsafeBufferPointer<Any.Type>,
1726-
/// resultBuffer: Builtin.RawPointer,
1727-
/// substitutions: UnsafeRawPointer?,
1728-
/// witnessTables: UnsafeRawPointer?,
1729-
/// numWitnessTables: UInt
1730-
/// ) async throws
1731-
using TargetExecutorSignature =
1732-
AsyncSignature<void(/*on=*/DefaultActor *,
1733-
/*targetName=*/const char *, /*targetNameSize=*/size_t,
1734-
/*argumentBuffer=*/void *,
1735-
/*argumentTypes=*/const Metadata *const *,
1736-
/*resultBuffer=*/void *,
1737-
/*substitutions=*/void *,
1738-
/*witnessTables=*/void **,
1739-
/*numWitnessTables=*/size_t,
1740-
/*resumeFunc=*/TaskContinuationFunction *,
1741-
/*callContext=*/AsyncContext *),
1742-
/*throws=*/true>;
1743-
1744-
SWIFT_CC(swiftasync)
1745-
SWIFT_RUNTIME_STDLIB_SPI
1746-
TargetExecutorSignature::FunctionType swift_distributed_execute_target;
1747-
1748-
/// Accessor takes:
1749-
/// - an async context
1750-
/// - an argument buffer as a raw pointer
1751-
/// - a list of all argument types (with substitutions applied)
1752-
/// - a result buffer as a raw pointer
1753-
/// - a list of substitutions
1754-
/// - a list of witness tables
1755-
/// - a number of witness tables in the buffer
1756-
/// - a reference to an actor to execute method on.
1757-
using DistributedAccessorSignature =
1758-
AsyncSignature<void(/*argumentBuffer=*/void *,
1759-
/*argumentTypes=*/const Metadata *const *,
1760-
/*resultBuffer=*/void *,
1761-
/*substitutions=*/void *,
1762-
/*witnessTables=*/void **,
1763-
/*numWitnessTables=*/size_t,
1764-
/*actor=*/HeapObject *),
1765-
/*throws=*/true>;
1766-
1767-
SWIFT_CC(swiftasync)
1768-
static DistributedAccessorSignature::ContinuationType
1769-
swift_distributed_execute_target_resume;
1770-
1771-
SWIFT_CC(swiftasync)
1772-
static void ::swift_distributed_execute_target_resume(
1773-
SWIFT_ASYNC_CONTEXT AsyncContext *context,
1774-
SWIFT_CONTEXT SwiftError *error) {
1775-
auto parentCtx = context->Parent;
1776-
auto resumeInParent =
1777-
reinterpret_cast<TargetExecutorSignature::ContinuationType *>(
1778-
parentCtx->ResumeParent);
1779-
swift_task_dealloc(context);
1780-
// See `swift_distributed_execute_target` - `parentCtx` in this case
1781-
// is `callContext` which should be completely transparent on resume.
1782-
return resumeInParent(parentCtx->Parent, error);
1783-
}
1784-
1785-
SWIFT_CC(swiftasync)
1786-
void ::swift_distributed_execute_target(
1787-
SWIFT_ASYNC_CONTEXT AsyncContext *callerContext,
1788-
DefaultActor *actor,
1789-
const char *targetNameStart, size_t targetNameLength,
1790-
void *argumentBuffer,
1791-
const Metadata *const *argumentTypes,
1792-
void *resultBuffer,
1793-
void *substitutions,
1794-
void **witnessTables,
1795-
size_t numWitnessTables,
1796-
TaskContinuationFunction *resumeFunc,
1797-
AsyncContext *callContext) {
1798-
auto *accessor = findDistributedAccessor(targetNameStart, targetNameLength);
1799-
if (!accessor) {
1800-
assert(false && "no distributed accessor");
1801-
return; // FIXME(distributed): return -1 here so the lib can fail the call
1802-
}
1803-
1804-
auto *asyncFnPtr = reinterpret_cast<
1805-
const AsyncFunctionPointer<DistributedAccessorSignature> *>(
1806-
accessor->Function.get());
1807-
assert(asyncFnPtr && "no function pointer for distributed_execute_target");
1808-
1809-
DistributedAccessorSignature::FunctionType *accessorEntry =
1810-
asyncFnPtr->Function.get();
1811-
1812-
AsyncContext *calleeContext = reinterpret_cast<AsyncContext *>(
1813-
swift_task_alloc(asyncFnPtr->ExpectedContextSize));
1814-
1815-
// TODO(concurrency): Special functions like this one are currently set-up
1816-
// to pass "caller" context and resume function as extra parameters due to
1817-
// how they are declared in C. But this particular function behaves exactly
1818-
// like a regular `async throws`, which means that we need to initialize
1819-
// intermediate `callContext` using parent `callerContext`. A better fix for
1820-
// this situation would be to adjust IRGen and handle function like this
1821-
// like regular `async` functions even though they are classified as special.
1822-
callContext->Parent = callerContext;
1823-
callContext->ResumeParent = resumeFunc;
1824-
1825-
calleeContext->Parent = callContext;
1826-
calleeContext->ResumeParent = reinterpret_cast<TaskContinuationFunction *>(
1827-
swift_distributed_execute_target_resume);
1828-
1829-
accessorEntry(calleeContext,
1830-
argumentBuffer, argumentTypes,
1831-
resultBuffer,
1832-
substitutions,
1833-
witnessTables,
1834-
numWitnessTables,
1835-
actor);
1836-
}

stdlib/public/Distributed/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ set(swift_distributed_link_libraries
1515

1616

1717
add_swift_target_library(swift_Distributed ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB
18+
DistributedActor.cpp
1819
AssertDistributed.swift
1920
DistributedActor.swift
2021
DistributedActorSystem.swift
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
///===--- DistributedActor.cpp - Distributed actor implementation ----------===///
2+
///
3+
/// This source file is part of the Swift.org open source project
4+
///
5+
/// Copyright (c) 2014 - 2021 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+
/// The implementation of Swift distributed actors.
14+
///
15+
///===----------------------------------------------------------------------===///
16+
17+
#include "swift/ABI/Task.h"
18+
#include "swift/ABI/Actor.h"
19+
#include "swift/ABI/Metadata.h"
20+
#include "swift/Runtime/AccessibleFunction.h"
21+
#include "swift/Runtime/Concurrency.h"
22+
23+
using namespace swift;
24+
25+
static const AccessibleFunctionRecord *
26+
findDistributedAccessor(const char *targetNameStart, size_t targetNameLength) {
27+
if (auto *func = runtime::swift_findAccessibleFunction(targetNameStart,
28+
targetNameLength)) {
29+
assert(func->Flags.isDistributed());
30+
return func;
31+
}
32+
return nullptr;
33+
}
34+
35+
SWIFT_CC(swift)
36+
SWIFT_EXPORT_FROM(swift_Distributed)
37+
void *swift_distributed_getGenericEnvironment(const char *targetNameStart,
38+
size_t targetNameLength) {
39+
auto *accessor = findDistributedAccessor(targetNameStart, targetNameLength);
40+
return accessor ? accessor->GenericEnvironment.get() : nullptr;
41+
}
42+
43+
/// func _executeDistributedTarget(
44+
/// on: AnyObject,
45+
/// _ targetName: UnsafePointer<UInt8>,
46+
/// _ targetNameLength: UInt,
47+
/// argumentBuffer: Builtin.RawPointer,
48+
/// argumentTypes: UnsafeBufferPointer<Any.Type>,
49+
/// resultBuffer: Builtin.RawPointer,
50+
/// substitutions: UnsafeRawPointer?,
51+
/// witnessTables: UnsafeRawPointer?,
52+
/// numWitnessTables: UInt
53+
/// ) async throws
54+
using TargetExecutorSignature =
55+
AsyncSignature<void(/*on=*/DefaultActor *,
56+
/*targetName=*/const char *, /*targetNameSize=*/size_t,
57+
/*argumentBuffer=*/void *,
58+
/*argumentTypes=*/const Metadata *const *,
59+
/*resultBuffer=*/void *,
60+
/*substitutions=*/void *,
61+
/*witnessTables=*/void **,
62+
/*numWitnessTables=*/size_t,
63+
/*resumeFunc=*/TaskContinuationFunction *,
64+
/*callContext=*/AsyncContext *),
65+
/*throws=*/true>;
66+
67+
SWIFT_CC(swiftasync)
68+
SWIFT_EXPORT_FROM(swift_Distributed)
69+
TargetExecutorSignature::FunctionType swift_distributed_execute_target;
70+
71+
/// Accessor takes:
72+
/// - an async context
73+
/// - an argument buffer as a raw pointer
74+
/// - a list of all argument types (with substitutions applied)
75+
/// - a result buffer as a raw pointer
76+
/// - a list of substitutions
77+
/// - a list of witness tables
78+
/// - a number of witness tables in the buffer
79+
/// - a reference to an actor to execute method on.
80+
using DistributedAccessorSignature =
81+
AsyncSignature<void(/*argumentBuffer=*/void *,
82+
/*argumentTypes=*/const Metadata *const *,
83+
/*resultBuffer=*/void *,
84+
/*substitutions=*/void *,
85+
/*witnessTables=*/void **,
86+
/*numWitnessTables=*/size_t,
87+
/*actor=*/HeapObject *),
88+
/*throws=*/true>;
89+
90+
SWIFT_CC(swiftasync)
91+
static DistributedAccessorSignature::ContinuationType
92+
swift_distributed_execute_target_resume;
93+
94+
SWIFT_CC(swiftasync)
95+
static void ::swift_distributed_execute_target_resume(
96+
SWIFT_ASYNC_CONTEXT AsyncContext *context,
97+
SWIFT_CONTEXT SwiftError *error) {
98+
auto parentCtx = context->Parent;
99+
auto resumeInParent =
100+
reinterpret_cast<TargetExecutorSignature::ContinuationType *>(
101+
parentCtx->ResumeParent);
102+
swift_task_dealloc(context);
103+
// See `swift_distributed_execute_target` - `parentCtx` in this case
104+
// is `callContext` which should be completely transparent on resume.
105+
return resumeInParent(parentCtx->Parent, error);
106+
}
107+
108+
SWIFT_CC(swiftasync)
109+
void ::swift_distributed_execute_target(
110+
SWIFT_ASYNC_CONTEXT AsyncContext *callerContext,
111+
DefaultActor *actor,
112+
const char *targetNameStart, size_t targetNameLength,
113+
void *argumentBuffer,
114+
const Metadata *const *argumentTypes,
115+
void *resultBuffer,
116+
void *substitutions,
117+
void **witnessTables,
118+
size_t numWitnessTables,
119+
TaskContinuationFunction *resumeFunc,
120+
AsyncContext *callContext) {
121+
auto *accessor = findDistributedAccessor(targetNameStart, targetNameLength);
122+
if (!accessor) {
123+
assert(false && "no distributed accessor");
124+
return; // FIXME(distributed): return -1 here so the lib can fail the call
125+
}
126+
127+
auto *asyncFnPtr = reinterpret_cast<
128+
const AsyncFunctionPointer<DistributedAccessorSignature> *>(
129+
accessor->Function.get());
130+
assert(asyncFnPtr && "no function pointer for distributed_execute_target");
131+
132+
DistributedAccessorSignature::FunctionType *accessorEntry =
133+
asyncFnPtr->Function.get();
134+
135+
AsyncContext *calleeContext = reinterpret_cast<AsyncContext *>(
136+
swift_task_alloc(asyncFnPtr->ExpectedContextSize));
137+
138+
// TODO(concurrency): Special functions like this one are currently set-up
139+
// to pass "caller" context and resume function as extra parameters due to
140+
// how they are declared in C. But this particular function behaves exactly
141+
// like a regular `async throws`, which means that we need to initialize
142+
// intermediate `callContext` using parent `callerContext`. A better fix for
143+
// this situation would be to adjust IRGen and handle function like this
144+
// like regular `async` functions even though they are classified as special.
145+
callContext->Parent = callerContext;
146+
callContext->ResumeParent = resumeFunc;
147+
148+
calleeContext->Parent = callContext;
149+
calleeContext->ResumeParent = reinterpret_cast<TaskContinuationFunction *>(
150+
swift_distributed_execute_target_resume);
151+
152+
accessorEntry(calleeContext,
153+
argumentBuffer, argumentTypes,
154+
resultBuffer,
155+
substitutions,
156+
witnessTables,
157+
numWitnessTables,
158+
actor);
159+
}

stdlib/public/Distributed/DistributedMetadata.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func __getReturnTypeInfo(
9494
/// Retrieve a generic environment descriptor associated with
9595
/// the given distributed target
9696
@available(SwiftStdlib 5.6, *)
97-
@_silgen_name("swift_distributed_get_generic_environment")
97+
@_silgen_name("swift_distributed_getGenericEnvironment")
9898
public // SPI _Distributed
9999
func _getGenericEnvironmentOfDistributedTarget(
100100
_ targetNameStart: UnsafePointer<UInt8>,

0 commit comments

Comments
 (0)