mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[embedded] Introduce a new swift_taskGroup_initializeWithOptions runtime entrypoint
This commit is contained in:
@@ -2792,10 +2792,6 @@ public:
|
|||||||
/// Request the TaskGroup to immediately release completed tasks,
|
/// Request the TaskGroup to immediately release completed tasks,
|
||||||
/// and not store their results. This also effectively disables `next()`.
|
/// and not store their results. This also effectively disables `next()`.
|
||||||
TaskGroup_DiscardResults = 8,
|
TaskGroup_DiscardResults = 8,
|
||||||
/// The `Metadata *T` in swift_taskGroup_initialize and in
|
|
||||||
/// swift_taskGroup_initializeWithFlags pointer is actually a
|
|
||||||
/// TaskOptionRecord pointer. Used only in Embedded Swift.
|
|
||||||
TaskGroup_MetadataAsOptionRecord = 9,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit TaskGroupFlags(uint32_t bits) : FlagSet(bits) {}
|
explicit TaskGroupFlags(uint32_t bits) : FlagSet(bits) {}
|
||||||
@@ -2804,10 +2800,6 @@ public:
|
|||||||
FLAGSET_DEFINE_FLAG_ACCESSORS(TaskGroup_DiscardResults,
|
FLAGSET_DEFINE_FLAG_ACCESSORS(TaskGroup_DiscardResults,
|
||||||
isDiscardResults,
|
isDiscardResults,
|
||||||
setIsDiscardResults)
|
setIsDiscardResults)
|
||||||
|
|
||||||
FLAGSET_DEFINE_FLAG_ACCESSORS(TaskGroup_MetadataAsOptionRecord,
|
|
||||||
isMetadataAsOptionRecord,
|
|
||||||
setIsMetadataAsOptionRecord)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Flags for cancellation records.
|
/// Flags for cancellation records.
|
||||||
|
|||||||
@@ -215,6 +215,17 @@ void swift_taskGroup_initialize(TaskGroup *group, const Metadata *T);
|
|||||||
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
|
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
|
||||||
void swift_taskGroup_initializeWithFlags(size_t flags, TaskGroup *group, const Metadata *T);
|
void swift_taskGroup_initializeWithFlags(size_t flags, TaskGroup *group, const Metadata *T);
|
||||||
|
|
||||||
|
/// Initialize a `TaskGroup` in the passed `group` memory location.
|
||||||
|
/// The caller is responsible for retaining and managing the group's lifecycle.
|
||||||
|
///
|
||||||
|
/// Its Swift signature is
|
||||||
|
///
|
||||||
|
/// \code
|
||||||
|
/// func swift_taskGroup_initialize(flags: Int, group: Builtin.RawPointer)
|
||||||
|
/// \endcode
|
||||||
|
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
|
||||||
|
void swift_taskGroup_initializeWithOptions(size_t flags, TaskGroup *group, const Metadata *T, TaskOptionRecord *options);
|
||||||
|
|
||||||
/// Attach a child task to the parent task's task group record.
|
/// Attach a child task to the parent task's task group record.
|
||||||
///
|
///
|
||||||
/// This function MUST be called from the AsyncTask running the task group.
|
/// This function MUST be called from the AsyncTask running the task group.
|
||||||
|
|||||||
@@ -2555,7 +2555,7 @@ FUNCTION(TaskRunInline,
|
|||||||
EFFECT(NoEffect),
|
EFFECT(NoEffect),
|
||||||
UNKNOWN_MEMEFFECTS)
|
UNKNOWN_MEMEFFECTS)
|
||||||
|
|
||||||
// void swift_taskGroup_initialize(TaskGroup *group);
|
// void swift_taskGroup_initialize(TaskGroup *group, const Metadata *T);
|
||||||
FUNCTION(TaskGroupInitialize,
|
FUNCTION(TaskGroupInitialize,
|
||||||
swift_taskGroup_initialize, SwiftCC,
|
swift_taskGroup_initialize, SwiftCC,
|
||||||
ConcurrencyAvailability,
|
ConcurrencyAvailability,
|
||||||
@@ -2565,7 +2565,7 @@ FUNCTION(TaskGroupInitialize,
|
|||||||
EFFECT(Concurrency),
|
EFFECT(Concurrency),
|
||||||
UNKNOWN_MEMEFFECTS)
|
UNKNOWN_MEMEFFECTS)
|
||||||
|
|
||||||
// void swift_taskGroup_initializeWithFlags(size_t flags, TaskGroup *group);
|
// void swift_taskGroup_initializeWithFlags(size_t flags, TaskGroup *group, const Metadata *T);
|
||||||
FUNCTION(TaskGroupInitializeWithFlags,
|
FUNCTION(TaskGroupInitializeWithFlags,
|
||||||
swift_taskGroup_initializeWithFlags, SwiftCC,
|
swift_taskGroup_initializeWithFlags, SwiftCC,
|
||||||
ConcurrencyDiscardingTaskGroupAvailability,
|
ConcurrencyDiscardingTaskGroupAvailability,
|
||||||
@@ -2578,6 +2578,20 @@ FUNCTION(TaskGroupInitializeWithFlags,
|
|||||||
EFFECT(Concurrency),
|
EFFECT(Concurrency),
|
||||||
UNKNOWN_MEMEFFECTS)
|
UNKNOWN_MEMEFFECTS)
|
||||||
|
|
||||||
|
// void swift_taskGroup_initializeWithTaskOptions(size_t flags, TaskGroup *group, const Metadata *T, TaskOptionRecord *options);
|
||||||
|
FUNCTION(TaskGroupInitializeWithOptions,
|
||||||
|
swift_taskGroup_initializeWithOptions, SwiftCC,
|
||||||
|
ConcurrencyDiscardingTaskGroupAvailability,
|
||||||
|
RETURNS(VoidTy),
|
||||||
|
ARGS(SizeTy, // flags
|
||||||
|
Int8PtrTy, // group
|
||||||
|
TypeMetadataPtrTy, // T.Type
|
||||||
|
SwiftTaskOptionRecordPtrTy // options
|
||||||
|
),
|
||||||
|
ATTRS(NoUnwind),
|
||||||
|
EFFECT(Concurrency),
|
||||||
|
UNKNOWN_MEMEFFECTS)
|
||||||
|
|
||||||
// void swift_taskGroup_destroy(TaskGroup *group);
|
// void swift_taskGroup_destroy(TaskGroup *group);
|
||||||
FUNCTION(TaskGroupDestroy,
|
FUNCTION(TaskGroupDestroy,
|
||||||
swift_taskGroup_destroy, SwiftCC,
|
swift_taskGroup_destroy, SwiftCC,
|
||||||
|
|||||||
@@ -336,38 +336,30 @@ llvm::Value *irgen::emitCreateTaskGroup(IRGenFunction &IGF,
|
|||||||
"createTaskGroup should have a type substitution");
|
"createTaskGroup should have a type substitution");
|
||||||
auto resultType = subs.getReplacementTypes()[0]->getCanonicalType();
|
auto resultType = subs.getReplacementTypes()[0]->getCanonicalType();
|
||||||
|
|
||||||
// In desktop Swift, we pass a Metadata pointer as the last argument. In
|
|
||||||
// Embedded Swift, we pass a TaskOptionRecord list, and mark a bit in
|
|
||||||
// groupFlags.
|
|
||||||
llvm::Value *metadataOrTypeOptionRecord;
|
|
||||||
if (IGF.IGM.Context.LangOpts.hasFeature(Feature::Embedded)) {
|
if (IGF.IGM.Context.LangOpts.hasFeature(Feature::Embedded)) {
|
||||||
metadataOrTypeOptionRecord =
|
// In Embedded Swift, call swift_taskGroup_initializeWithOptions instead, to
|
||||||
llvm::ConstantPointerNull::get(IGF.IGM.Int8PtrTy);
|
// avoid needing a Metadata argument.
|
||||||
metadataOrTypeOptionRecord = maybeAddEmbeddedSwiftResultTypeInfo(
|
llvm::Value *options = llvm::ConstantPointerNull::get(IGF.IGM.Int8PtrTy);
|
||||||
IGF, metadataOrTypeOptionRecord, resultType);
|
llvm::Value *resultTypeMetadata = llvm::ConstantPointerNull::get(IGF.IGM.Int8PtrTy);
|
||||||
llvm::IntegerType *IntPtrTy = IGF.IGM.IntPtrTy;
|
options = maybeAddEmbeddedSwiftResultTypeInfo(IGF, options, resultType);
|
||||||
TaskGroupFlags taskgroupFlags(0);
|
if (!groupFlags) groupFlags = llvm::ConstantInt::get(IGF.IGM.SizeTy, 0);
|
||||||
taskgroupFlags.setIsMetadataAsOptionRecord(true);
|
llvm::CallInst *call = IGF.Builder.CreateCall(IGF.IGM.getTaskGroupInitializeWithOptionsFunctionPointer(),
|
||||||
auto flagValue = llvm::ConstantInt::get(IGF.IGM.IntPtrTy,
|
{groupFlags, group, resultTypeMetadata, options});
|
||||||
taskgroupFlags.getOpaqueValue());
|
call->setDoesNotThrow();
|
||||||
if (!groupFlags) {
|
call->setCallingConv(IGF.IGM.SwiftCC);
|
||||||
groupFlags = flagValue;
|
return group;
|
||||||
} else {
|
|
||||||
groupFlags = IGF.Builder.CreateOr(groupFlags, flagValue);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
metadataOrTypeOptionRecord = IGF.emitAbstractTypeMetadataRef(resultType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto resultTypeMetadata = IGF.emitAbstractTypeMetadataRef(resultType);
|
||||||
|
|
||||||
llvm::CallInst *call;
|
llvm::CallInst *call;
|
||||||
if (groupFlags) {
|
if (groupFlags) {
|
||||||
call = IGF.Builder.CreateCall(
|
call = IGF.Builder.CreateCall(IGF.IGM.getTaskGroupInitializeWithFlagsFunctionPointer(),
|
||||||
IGF.IGM.getTaskGroupInitializeWithFlagsFunctionPointer(),
|
{groupFlags, group, resultTypeMetadata});
|
||||||
{groupFlags, group, metadataOrTypeOptionRecord});
|
|
||||||
} else {
|
} else {
|
||||||
call =
|
call =
|
||||||
IGF.Builder.CreateCall(IGF.IGM.getTaskGroupInitializeFunctionPointer(),
|
IGF.Builder.CreateCall(IGF.IGM.getTaskGroupInitializeFunctionPointer(),
|
||||||
{group, metadataOrTypeOptionRecord});
|
{group, resultTypeMetadata});
|
||||||
}
|
}
|
||||||
call->setDoesNotThrow();
|
call->setDoesNotThrow();
|
||||||
call->setCallingConv(IGF.IGM.SwiftCC);
|
call->setCallingConv(IGF.IGM.SwiftCC);
|
||||||
|
|||||||
@@ -300,6 +300,10 @@ OVERRIDE_TASK_GROUP(taskGroup_initializeWithFlags, void,
|
|||||||
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift),
|
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift),
|
||||||
swift::, (size_t flags, TaskGroup *group, const Metadata *T), (flags, group, T))
|
swift::, (size_t flags, TaskGroup *group, const Metadata *T), (flags, group, T))
|
||||||
|
|
||||||
|
OVERRIDE_TASK_GROUP(taskGroup_initializeWithOptions, void,
|
||||||
|
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift),
|
||||||
|
swift::, (size_t flags, TaskGroup *group, const Metadata *T, TaskOptionRecord *options), (flags, group, T, options))
|
||||||
|
|
||||||
OVERRIDE_TASK_STATUS(taskGroup_attachChild, void,
|
OVERRIDE_TASK_STATUS(taskGroup_attachChild, void,
|
||||||
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift),
|
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift),
|
||||||
swift::, (TaskGroup *group, AsyncTask *child),
|
swift::, (TaskGroup *group, AsyncTask *child),
|
||||||
|
|||||||
@@ -955,6 +955,8 @@ TaskGroup* TaskGroupTaskStatusRecord::getGroup() {
|
|||||||
// =============================================================================
|
// =============================================================================
|
||||||
// ==== initialize -------------------------------------------------------------
|
// ==== initialize -------------------------------------------------------------
|
||||||
|
|
||||||
|
static void _swift_taskGroup_initialize(ResultTypeInfo resultType, size_t rawGroupFlags, TaskGroup *group);
|
||||||
|
|
||||||
// Initializes into the preallocated _group an actual TaskGroupBase.
|
// Initializes into the preallocated _group an actual TaskGroupBase.
|
||||||
SWIFT_CC(swift)
|
SWIFT_CC(swift)
|
||||||
static void swift_taskGroup_initializeImpl(TaskGroup *group, const Metadata *T) {
|
static void swift_taskGroup_initializeImpl(TaskGroup *group, const Metadata *T) {
|
||||||
@@ -965,21 +967,27 @@ static void swift_taskGroup_initializeImpl(TaskGroup *group, const Metadata *T)
|
|||||||
SWIFT_CC(swift)
|
SWIFT_CC(swift)
|
||||||
static void swift_taskGroup_initializeWithFlagsImpl(size_t rawGroupFlags,
|
static void swift_taskGroup_initializeWithFlagsImpl(size_t rawGroupFlags,
|
||||||
TaskGroup *group, const Metadata *T) {
|
TaskGroup *group, const Metadata *T) {
|
||||||
TaskGroupFlags groupFlags(rawGroupFlags);
|
|
||||||
SWIFT_TASK_GROUP_DEBUG_LOG_0(group, "create group, from task:%p; flags: isDiscardingResults=%d",
|
|
||||||
swift_task_getCurrent(),
|
|
||||||
groupFlags.isDiscardResults());
|
|
||||||
|
|
||||||
ResultTypeInfo resultType;
|
ResultTypeInfo resultType;
|
||||||
#if !SWIFT_CONCURRENCY_EMBEDDED
|
#if !SWIFT_CONCURRENCY_EMBEDDED
|
||||||
resultType.metadata = T;
|
resultType.metadata = T;
|
||||||
assert(!groupFlags.isMetadataAsOptionRecord());
|
|
||||||
#else
|
#else
|
||||||
assert(groupFlags.isMetadataAsOptionRecord());
|
swift_unreachable("swift_taskGroup_initializeWithFlags in embedded");
|
||||||
TaskOptionRecord *options = (TaskOptionRecord *)T;
|
#endif
|
||||||
|
_swift_taskGroup_initialize(resultType, rawGroupFlags, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initializes into the preallocated _group an actual instance.
|
||||||
|
SWIFT_CC(swift)
|
||||||
|
static void swift_taskGroup_initializeWithOptionsImpl(size_t rawGroupFlags, TaskGroup *group, const Metadata *T, TaskOptionRecord *options) {
|
||||||
|
ResultTypeInfo resultType;
|
||||||
|
#if !SWIFT_CONCURRENCY_EMBEDDED
|
||||||
|
resultType.metadata = T;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (auto option = options; option; option = option->getParent()) {
|
for (auto option = options; option; option = option->getParent()) {
|
||||||
switch (option->getKind()) {
|
switch (option->getKind()) {
|
||||||
case TaskOptionRecordKind::ResultTypeInfo: {
|
case TaskOptionRecordKind::ResultTypeInfo: {
|
||||||
|
#if SWIFT_CONCURRENCY_EMBEDDED
|
||||||
auto *typeInfo = cast<ResultTypeInfoTaskOptionRecord>(option);
|
auto *typeInfo = cast<ResultTypeInfoTaskOptionRecord>(option);
|
||||||
resultType = {
|
resultType = {
|
||||||
.size = typeInfo->size,
|
.size = typeInfo->size,
|
||||||
@@ -988,13 +996,26 @@ static void swift_taskGroup_initializeWithFlagsImpl(size_t rawGroupFlags,
|
|||||||
.storeEnumTagSinglePayload = typeInfo->storeEnumTagSinglePayload,
|
.storeEnumTagSinglePayload = typeInfo->storeEnumTagSinglePayload,
|
||||||
.destroy = typeInfo->destroy,
|
.destroy = typeInfo->destroy,
|
||||||
};
|
};
|
||||||
|
#else
|
||||||
|
swift_unreachable("ResultTypeInfo in non embedded");
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
swift_unreachable("only ResultTypeInfo expected");
|
break; // ignore unknown records
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
assert(!resultType.isNull());
|
||||||
|
|
||||||
|
_swift_taskGroup_initialize(resultType, rawGroupFlags, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _swift_taskGroup_initialize(ResultTypeInfo resultType, size_t rawGroupFlags, TaskGroup *group) {
|
||||||
|
TaskGroupFlags groupFlags(rawGroupFlags);
|
||||||
|
SWIFT_TASK_GROUP_DEBUG_LOG_0(group, "create group, from task:%p; flags: isDiscardingResults=%d",
|
||||||
|
swift_task_getCurrent(),
|
||||||
|
groupFlags.isDiscardResults());
|
||||||
|
|
||||||
TaskGroupBase *impl;
|
TaskGroupBase *impl;
|
||||||
if (groupFlags.isDiscardResults()) {
|
if (groupFlags.isDiscardResults()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user