Skip to content

Commit 1a0ff97

Browse files
committed
[embedded] Add null checks of futureResultType back (allow non-future tasks)
1 parent 74dd5a9 commit 1a0ff97

File tree

2 files changed

+37
-19
lines changed

2 files changed

+37
-19
lines changed

include/swift/ABI/Task.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ class NullaryContinuationJob : public Job {
197197
struct ResultTypeInfo {
198198
#if !SWIFT_CONCURRENCY_EMBEDDED
199199
const Metadata *metadata = nullptr;
200+
bool isNull() {
201+
return metadata == nullptr;
202+
}
200203
size_t vw_size() {
201204
return metadata->vw_size();
202205
}
@@ -221,6 +224,9 @@ struct ResultTypeInfo {
221224
unsigned emptyCases) = nullptr;
222225
void (*destroy)(OpaqueValue *) = nullptr;
223226

227+
bool isNull() {
228+
return initializeWithCopy == nullptr;
229+
}
224230
size_t vw_size() {
225231
return size;
226232
}

stdlib/public/Concurrency/Task.cpp

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -606,10 +606,14 @@ static std::pair<size_t, size_t> amountToAllocateForHeaderAndTask(
606606
if (group) {
607607
headerSize += sizeof(AsyncTask::GroupChildFragment);
608608
}
609-
610-
headerSize += FutureFragment::fragmentSize(headerSize, futureResultType);
611-
// Add the future async context prefix.
612-
headerSize += sizeof(FutureAsyncContextPrefix);
609+
if (!futureResultType.isNull()) {
610+
headerSize += FutureFragment::fragmentSize(headerSize, futureResultType);
611+
// Add the future async context prefix.
612+
headerSize += sizeof(FutureAsyncContextPrefix);
613+
} else {
614+
// Add the async context prefix.
615+
headerSize += sizeof(AsyncContextPrefix);
616+
}
613617

614618
headerSize = llvm::alignTo(headerSize, llvm::Align(alignof(AsyncContext)));
615619
// Allocate the initial context together with the job.
@@ -636,9 +640,6 @@ static AsyncTaskAndContext swift_task_create_commonImpl(
636640
// Propagate task-creation flags to job flags as appropriate.
637641
jobFlags.task_setIsChildTask(taskCreateFlags.isChildTask());
638642

639-
jobFlags.task_setIsFuture(true);
640-
assert(initialContextSize >= sizeof(FutureAsyncContext));
641-
642643
ResultTypeInfo futureResultType;
643644
#if !SWIFT_CONCURRENCY_EMBEDDED
644645
futureResultType.metadata = futureResultTypeMetadata;
@@ -705,6 +706,15 @@ static AsyncTaskAndContext swift_task_create_commonImpl(
705706
}
706707
}
707708

709+
#if SWIFT_CONCURRENCY_EMBEDDED
710+
assert(!futureResultType.isNull());
711+
#endif
712+
713+
if (!futureResultType.isNull()) {
714+
jobFlags.task_setIsFuture(true);
715+
assert(initialContextSize >= sizeof(FutureAsyncContext));
716+
}
717+
708718
// Add to the task group, if requested.
709719
if (taskCreateFlags.addPendingGroupTaskUnconditionally()) {
710720
assert(group && "Missing group");
@@ -853,7 +863,7 @@ static AsyncTaskAndContext swift_task_create_commonImpl(
853863
// the async context to get at the parameters.
854864
// See e.g. FutureAsyncContextPrefix.
855865

856-
if (taskCreateFlags.isDiscardingTask()) {
866+
if (futureResultType.isNull() || taskCreateFlags.isDiscardingTask()) {
857867
auto asyncContextPrefix = reinterpret_cast<AsyncContextPrefix *>(
858868
reinterpret_cast<char *>(allocation) + headerSize -
859869
sizeof(AsyncContextPrefix));
@@ -903,17 +913,19 @@ static AsyncTaskAndContext swift_task_create_commonImpl(
903913
}
904914

905915
// Initialize the future fragment if applicable.
906-
assert(task->isFuture());
907-
auto futureFragment = task->futureFragment();
908-
::new (futureFragment) FutureFragment(futureResultType);
909-
910-
// Set up the context for the future so there is no error, and a successful
911-
// result will be written into the future fragment's storage.
912-
auto futureAsyncContextPrefix =
913-
reinterpret_cast<FutureAsyncContextPrefix *>(
914-
reinterpret_cast<char *>(allocation) + headerSize -
915-
sizeof(FutureAsyncContextPrefix));
916-
futureAsyncContextPrefix->indirectResult = futureFragment->getStoragePtr();
916+
if (!futureResultType.isNull()) {
917+
assert(task->isFuture());
918+
auto futureFragment = task->futureFragment();
919+
::new (futureFragment) FutureFragment(futureResultType);
920+
921+
// Set up the context for the future so there is no error, and a successful
922+
// result will be written into the future fragment's storage.
923+
auto futureAsyncContextPrefix =
924+
reinterpret_cast<FutureAsyncContextPrefix *>(
925+
reinterpret_cast<char *>(allocation) + headerSize -
926+
sizeof(FutureAsyncContextPrefix));
927+
futureAsyncContextPrefix->indirectResult = futureFragment->getStoragePtr();
928+
}
917929

918930
SWIFT_TASK_DEBUG_LOG("creating task %p ID %" PRIu64
919931
" with parent %p at base pri %zu",

0 commit comments

Comments
 (0)