[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 // 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 // by this executor or not. Default value for executors which do not implement
// `isIsolatingCurrentContext`. // `isIsolatingCurrentContext`.
Unknown, Unknown = -1,
// The current context is definitely not isolated by this executor. // The current context is definitely not isolated by this executor.
NotIsolated, NotIsolated = 0,
// The current context is definitely isolated by this executor. // The current context is definitely isolated by this executor.
Isolated, Isolated = 1,
}; };
IsIsolatingCurrentContextDecision IsIsolatingCurrentContextDecision

View File

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

View File

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

View File

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

View File

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

View File

@@ -31,8 +31,6 @@
#define __ptrauth_objc_isa_pointer #define __ptrauth_objc_isa_pointer
#endif #endif
#include "swift/ABI/Executor.h"
#include <inttypes.h> #include <inttypes.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
@@ -228,12 +226,15 @@ swift_executor_invokeSwiftCheckIsolated(SwiftExecutorRef executor) {
return _swift_task_invokeSwiftCheckIsolated_c(executor); return _swift_task_invokeSwiftCheckIsolated_c(executor);
} }
using swift::IsIsolatingCurrentContextDecision;
/// Check if the current context is isolated by the specified executor. /// 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) { 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); 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); SWIFT_CC(swift) void swift_task_checkIsolatedImpl(SwiftExecutorRef executor);
/// Check if the specified executor isolates the current context. /// Check if the specified executor isolates the current context.
SWIFT_CC(swift) SWIFT_CC(swift) int8_t
swift::IsIsolatingCurrentContextDecision swift_task_isIsolatingCurrentContextImpl(SwiftExecutorRef executor); swift_task_isIsolatingCurrentContextImpl(SwiftExecutorRef executor);
/// Get a reference to the main executor. /// Get a reference to the main executor.
SWIFT_CC(swift) SwiftExecutorRef swift_task_getMainExecutorImpl(void); SWIFT_CC(swift) SwiftExecutorRef swift_task_getMainExecutorImpl(void);

View File

@@ -93,25 +93,26 @@ int8_t _task_serialExecutor_isIsolatingCurrentContext(
const Metadata *selfType, const Metadata *selfType,
const SerialExecutorWitnessTable *wtable); const SerialExecutorWitnessTable *wtable);
using swift::IsIsolatingCurrentContextDecision; SWIFT_CC(swift) int8_t
SWIFT_CC(swift) IsIsolatingCurrentContextDecision
swift::swift_task_invokeSwiftIsIsolatingCurrentContext(SerialExecutorRef executor) swift::swift_task_invokeSwiftIsIsolatingCurrentContext(SerialExecutorRef executor)
{ {
if (!executor.hasSerialExecutorWitnessTable()) { if (!executor.hasSerialExecutorWitnessTable()) {
return IsIsolatingCurrentContextDecision::NotIsolated; return static_cast<int8_t>(IsIsolatingCurrentContextDecision::NotIsolated);
} }
auto decision = _task_serialExecutor_isIsolatingCurrentContext( auto decision = _task_serialExecutor_isIsolatingCurrentContext(
executor.getIdentity(), swift_getObjectType(executor.getIdentity()), executor.getIdentity(), swift_getObjectType(executor.getIdentity()),
executor.getSerialExecutorWitnessTable()); 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) 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"); swift_Concurrency_fatalError(0, "Unexpected IsIsolatingCurrentContextDecision value");
} }
/*****************************************************************************/ /*****************************************************************************/
/****************************** MAIN EXECUTOR *******************************/ /****************************** MAIN EXECUTOR *******************************/
/*****************************************************************************/ /*****************************************************************************/

View File

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

View File

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