[embedded][Concurrency] Further refine C-api boundary for isIsolating...

This commit is contained in:
Konrad 'ktoso' Malawski
2025-04-29 22:28:31 +09:00
parent ea16df04ac
commit 6872707574
11 changed files with 44 additions and 40 deletions

View File

@@ -418,11 +418,11 @@ enum class IsIsolatingCurrentContextDecision : int8_t {
// The function call could not determine if the current context is isolated
// by this executor or not. Default value for executors which do not implement
// `isIsolatingCurrentContext`.
Unknown,
Unknown = -1,
// The current context is definitely not isolated by this executor.
NotIsolated,
NotIsolated = 0,
// The current context is definitely isolated by this executor.
Isolated,
Isolated = 1,
};
IsIsolatingCurrentContextDecision

View File

@@ -777,12 +777,12 @@ bool swift_task_invokeSwiftCheckIsolated(SerialExecutorRef executor);
/// Invoke an executor's `isIsolatingCurrentContext` implementation;
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
IsIsolatingCurrentContextDecision swift_task_isIsolatingCurrentContext(SerialExecutorRef executor);
int8_t swift_task_isIsolatingCurrentContext(SerialExecutorRef executor);
/// Invoke a Swift executor's `isIsolatingCurrentContext` implementation; returns
/// `true` if it invoked the Swift implementation, `false` otherwise.
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
IsIsolatingCurrentContextDecision swift_task_invokeSwiftIsIsolatingCurrentContext(SerialExecutorRef executor);
int8_t swift_task_invokeSwiftIsIsolatingCurrentContext(SerialExecutorRef executor);
/// A count in nanoseconds.
using JobDelay = unsigned long long;

View File

@@ -47,7 +47,7 @@ SWIFT_CONCURRENCY_HOOK(void, swift_task_enqueueGlobalWithDeadline,
SWIFT_CONCURRENCY_HOOK(void, swift_task_checkIsolated,
SerialExecutorRef executor);
SWIFT_CONCURRENCY_HOOK(IsIsolatingCurrentContextDecision, swift_task_isIsolatingCurrentContext,
SWIFT_CONCURRENCY_HOOK(int8_t, swift_task_isIsolatingCurrentContext,
SerialExecutorRef executor);
SWIFT_CONCURRENCY_HOOK(bool, swift_task_isOnExecutor,

View File

@@ -520,7 +520,9 @@ static bool swift_task_isCurrentExecutorWithFlagsImpl(
expectedExecutor.getIdentity());
// The executor has the most recent 'isIsolatingCurrentContext' API
// so available so we prefer calling that to 'checkIsolated'.
auto isIsolatingCurrentContextDecision = swift_task_isIsolatingCurrentContext(expectedExecutor);
auto isIsolatingCurrentContextDecision =
getIsIsolatingCurrentContextDecisionFromInt(
swift_task_isIsolatingCurrentContext(expectedExecutor));
SWIFT_TASK_DEBUG_LOG("executor checking mode option: UseIsIsolatingCurrentContext; invoke (%p).isIsolatingCurrentContext => %s",
expectedExecutor.getIdentity(), getIsIsolatingCurrentContextDecisionNameStr(isIsolatingCurrentContextDecision));
@@ -646,7 +648,8 @@ static bool swift_task_isCurrentExecutorWithFlagsImpl(
SWIFT_TASK_DEBUG_LOG("executor checking: call (%p).isIsolatingCurrentContext",
expectedExecutor.getIdentity());
const auto isIsolatingCurrentContextDecision = swift_task_isIsolatingCurrentContext(expectedExecutor);
const auto isIsolatingCurrentContextDecision =
getIsIsolatingCurrentContextDecisionFromInt(swift_task_isIsolatingCurrentContext(expectedExecutor));
SWIFT_TASK_DEBUG_LOG("executor checking: can call (%p).isIsolatingCurrentContext => %p",
expectedExecutor.getIdentity(), getIsIsolatingCurrentContextDecisionNameStr(isIsolatingCurrentContextDecision));

View File

@@ -111,18 +111,20 @@ swift::swift_task_checkIsolated(SerialExecutorRef executor) {
swift_task_checkIsolatedOrig(executor);
}
SWIFT_CC(swift) static IsIsolatingCurrentContextDecision
SWIFT_CC(swift) static int8_t
swift_task_isIsolatingCurrentContextOrig(SerialExecutorRef executor) {
return swift_task_isIsolatingCurrentContextImpl(
*reinterpret_cast<SwiftExecutorRef *>(&executor));
}
IsIsolatingCurrentContextDecision
int8_t
swift::swift_task_isIsolatingCurrentContext(SerialExecutorRef executor) {
if (SWIFT_UNLIKELY(swift_task_isIsolatingCurrentContext_hook))
return swift_task_isIsolatingCurrentContext_hook(executor, swift_task_isIsolatingCurrentContextOrig);
else
if (SWIFT_UNLIKELY(swift_task_isIsolatingCurrentContext_hook)) {
return swift_task_isIsolatingCurrentContext_hook(
executor, swift_task_isIsolatingCurrentContextOrig);
} else {
return swift_task_isIsolatingCurrentContextOrig(executor);
}
}
// Implemented in Swift because we need to obtain the user-defined flags on the executor ref.

View File

@@ -155,7 +155,7 @@ void swift_task_checkIsolatedImpl(SwiftExecutorRef executor) {
}
SWIFT_CC(swift)
IsIsolatingCurrentContextDecision swift_task_isIsolatingCurrentContextImpl(SwiftExecutorRef executor) {
int8_t swift_task_isIsolatingCurrentContextImpl(SwiftExecutorRef executor) {
return swift_executor_invokeSwiftIsIsolatingCurrentContext(executor);
}

View File

@@ -62,22 +62,20 @@ int8_t _swift_task_isIsolatingCurrentContextSwift(
const SerialExecutorWitnessTable *witnessTable
);
extern "C" SWIFT_CC(swift) IsIsolatingCurrentContextDecision swift_task_isIsolatingCurrentContextImpl(
extern "C" SWIFT_CC(swift) int8_t
swift_task_isIsolatingCurrentContextImpl(
SerialExecutorRef executor) {
HeapObject *identity = executor.getIdentity();
// We might be being called with an actor rather than a "proper"
// SerialExecutor; in that case, we won't have a SerialExecutor witness
// table.
if (!executor.hasSerialExecutorWitnessTable()) {
return IsIsolatingCurrentContextDecision::Unknown;
}
if (!executor.hasSerialExecutorWitnessTable())
return static_cast<uint8_t>(IsIsolatingCurrentContextDecision::Unknown);
auto decision = _swift_task_isIsolatingCurrentContextSwift(
return _swift_task_isIsolatingCurrentContextSwift(
identity, swift_getObjectType(identity),
executor.getSerialExecutorWitnessTable());
return getIsIsolatingCurrentContextDecisionFromInt(decision);
}
extern "C" SWIFT_CC(swift) bool swift_task_isMainExecutorImpl(

View File

@@ -31,8 +31,6 @@
#define __ptrauth_objc_isa_pointer
#endif
#include "swift/ABI/Executor.h"
#include <inttypes.h>
#include <stdbool.h>
#include <stdlib.h>
@@ -228,12 +226,15 @@ swift_executor_invokeSwiftCheckIsolated(SwiftExecutorRef executor) {
return _swift_task_invokeSwiftCheckIsolated_c(executor);
}
using swift::IsIsolatingCurrentContextDecision;
/// Check if the current context is isolated by the specified executor.
static inline IsIsolatingCurrentContextDecision
///
/// The numeric values correspond to `swift::IsIsolatingCurrentContextDecision`.
///
/// Specifically ONLY `1` means "isolated", while smaller values mean not isolated or unknown.
/// See ``IsIsolatingCurrentContextDecision`` for details.
static inline int8_t
swift_executor_invokeSwiftIsIsolatingCurrentContext(SwiftExecutorRef executor) {
extern IsIsolatingCurrentContextDecision _swift_task_invokeSwiftIsIsolatingCurrentContext_c(SwiftExecutorRef executor);
extern int8_t _swift_task_invokeSwiftIsIsolatingCurrentContext_c(SwiftExecutorRef executor);
return _swift_task_invokeSwiftIsIsolatingCurrentContext_c(executor);
}
@@ -296,8 +297,8 @@ SWIFT_CC(swift) void swift_task_enqueueMainExecutorImpl(SwiftJob * _Nonnull job)
SWIFT_CC(swift) void swift_task_checkIsolatedImpl(SwiftExecutorRef executor);
/// Check if the specified executor isolates the current context.
SWIFT_CC(swift)
swift::IsIsolatingCurrentContextDecision swift_task_isIsolatingCurrentContextImpl(SwiftExecutorRef executor);
SWIFT_CC(swift) int8_t
swift_task_isIsolatingCurrentContextImpl(SwiftExecutorRef executor);
/// Get a reference to the main executor.
SWIFT_CC(swift) SwiftExecutorRef swift_task_getMainExecutorImpl(void);

View File

@@ -93,25 +93,26 @@ int8_t _task_serialExecutor_isIsolatingCurrentContext(
const Metadata *selfType,
const SerialExecutorWitnessTable *wtable);
using swift::IsIsolatingCurrentContextDecision;
SWIFT_CC(swift) IsIsolatingCurrentContextDecision
SWIFT_CC(swift) int8_t
swift::swift_task_invokeSwiftIsIsolatingCurrentContext(SerialExecutorRef executor)
{
if (!executor.hasSerialExecutorWitnessTable()) {
return IsIsolatingCurrentContextDecision::NotIsolated;
return static_cast<int8_t>(IsIsolatingCurrentContextDecision::NotIsolated);
}
auto decision = _task_serialExecutor_isIsolatingCurrentContext(
executor.getIdentity(), swift_getObjectType(executor.getIdentity()),
executor.getSerialExecutorWitnessTable());
return getIsIsolatingCurrentContextDecisionFromInt(decision);
return decision;
}
extern "C" swift::IsIsolatingCurrentContextDecision _swift_task_invokeSwiftIsIsolatingCurrentContext_c(SwiftExecutorRef executor)
extern "C" int8_t
_swift_task_invokeSwiftIsIsolatingCurrentContext_c(SwiftExecutorRef executor)
{
return swift_task_invokeSwiftIsIsolatingCurrentContext(*reinterpret_cast<SerialExecutorRef *>(&executor));
return
static_cast<int8_t>(swift_task_invokeSwiftIsIsolatingCurrentContext(
*reinterpret_cast<SerialExecutorRef *>(&executor)));
}
extern "C" void _swift_job_run_c(SwiftJob *job, SwiftExecutorRef executor)
@@ -181,7 +182,6 @@ swift::getIsIsolatingCurrentContextDecisionNameStr(IsIsolatingCurrentContextDeci
swift_Concurrency_fatalError(0, "Unexpected IsIsolatingCurrentContextDecision value");
}
/*****************************************************************************/
/****************************** MAIN EXECUTOR *******************************/
/*****************************************************************************/

View File

@@ -308,7 +308,7 @@ void swift_task_checkIsolatedImpl(SwiftExecutorRef executor) {
/// Check if the specified executor is the current executor.
SWIFT_CC(swift)
IsIsolatingCurrentContextDecision swift_task_isIsolatingCurrentContextImpl(SwiftExecutorRef executor) {
int8_t swift_task_isIsolatingCurrentContextImpl(SwiftExecutorRef executor) {
return swift_executor_invokeSwiftIsIsolatingCurrentContext(executor);
}

View File

@@ -92,11 +92,11 @@ swift_task_checkIsolated_override(SerialExecutorRef executor,
}
SWIFT_CC(swift)
static bool
static int8_t
swift_task_isIsolatingCurrentContext_override(SerialExecutorRef executor,
swift_task_isIsolatingCurrentContext_original original) {
Ran = true;
return true;
return 0;
}
SWIFT_CC(swift)