Skip to content

Commit

Permalink
TaskGroup.addTask now also retains the task executor
Browse files Browse the repository at this point in the history
  • Loading branch information
ktoso committed Jun 5, 2024
1 parent 639f70a commit 707551e
Show file tree
Hide file tree
Showing 10 changed files with 36 additions and 106 deletions.
11 changes: 6 additions & 5 deletions include/swift/ABI/TaskOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,17 @@ class TaskGroupTaskOptionRecord : public TaskOptionRecord {

/// Task option to specify on what executor the task should be executed.
///
/// Not passing this option implies that an inferred (e.g. surrounding actor
/// when we inherit execution context) or the default executor should be used.
/// Not passing this option (or it's alternative "owned" version) implies that
/// an inferred (e.g. surrounding actor when we inherit execution context)
/// or the default executor should be used.
///
/// Lack of this option usually means that the global concurrent executor, or
/// the executor of the enclosing actor will be used.
class InitialTaskExecutorPreferenceTaskOptionRecord : public TaskOptionRecord {
class InitialTaskExecutorRefPreferenceTaskOptionRecord : public TaskOptionRecord {
const TaskExecutorRef Executor;

public:
InitialTaskExecutorPreferenceTaskOptionRecord(TaskExecutorRef executor)
InitialTaskExecutorRefPreferenceTaskOptionRecord(TaskExecutorRef executor)
: TaskOptionRecord(TaskOptionRecordKind::InitialTaskExecutorUnowned),
Executor(executor) {}

Expand All @@ -97,7 +98,7 @@ class InitialTaskExecutorPreferenceTaskOptionRecord : public TaskOptionRecord {
}
};

/// This is quite similar to `InitialTaskExecutorPreferenceTaskOptionRecord`
/// This is quite similar to `InitialTaskExecutorRefPreferenceTaskOptionRecord`
/// however it takes a "raw" TaskExecutor existential in the form of an Identity
/// and WitnessTable - rather than the specific UnownedTaskExecutor which already
/// may have specific "flags" set on it.
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/SILOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class SILOptions {
bool VerifyAll = false;

/// If true, no SIL verification is done at all.
bool VerifyNone = false; // FIXME: !!!!
bool VerifyNone = false;

/// Are we debugging sil serialization.
bool DebugSerialization = false;
Expand Down
26 changes: 4 additions & 22 deletions lib/AST/Builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1526,7 +1526,7 @@ Type swift::getAsyncTaskAndContextType(ASTContext &ctx) {
}

static ValueDecl *getCreateTask(ASTContext &ctx, Identifier id) {
auto f = getBuiltinFunction(
return getBuiltinFunction(
ctx, id, _thin, _generics(_unrestricted, _conformsToDefaults(0)),
_parameters(
_label("flags", _swiftInt),
Expand All @@ -1537,22 +1537,6 @@ static ValueDecl *getCreateTask(ASTContext &ctx, Identifier id) {
_label("operation", _function(_async(_throws(_sendable(_thick))),
_typeparam(0), _parameters()))),
_tuple(_nativeObject, _rawPointer));

fprintf(stderr, "[%s:%d](%s) the function: \n", __FILE_NAME__, __LINE__, __FUNCTION__);
f->dump();
// (func_decl implicit "createTask(flags:initialSerialExecutor:taskGroup:initialTaskExecutor:initialTaskExecutorConsuming:operation:)" "<T>" access=public
// (parameter_list
// 0 int - (parameter <anonymous @ 0x13820f638> apiName="flags" interface type="Int")
// 1 ptr - (parameter <anonymous @ 0x13820f6f0> apiName="initialSerialExecutor" interface type="Builtin.Executor?" default_arg=nil
// (expression=nil_literal_expr implicit type="<null>" initializer="**NULL**"))
// 2 ptr - (parameter <anonymous @ 0x13820f808> apiName="taskGroup" interface type="Builtin.RawPointer?" default_arg=nil
// (expression=nil_literal_expr implicit type="<null>" initializer="**NULL**"))
// 3 int - (parameter <anonymous @ 0x13820f900> apiName="initialTaskExecutor" interface type="Builtin.Executor?" default_arg=nil
// (expression=nil_literal_expr implicit type="<null>" initializer="**NULL**"))
// 4 int - (parameter <anonymous @ 0x13820fa18> apiName="initialTaskExecutorConsuming" interface type="TaskExecutor?" consuming default_arg=nil
// (expression=nil_literal_expr implicit type="<null>" initializer="**NULL**"))
// 5 func - (parameter <anonymous @ 0x13820fb60> apiName="operation" interface type="@Sendable () async throws -> T")))
return f;
}

static ValueDecl *getCreateDiscardingTask(ASTContext &ctx, Identifier id) {
Expand All @@ -1562,8 +1546,8 @@ static ValueDecl *getCreateDiscardingTask(ASTContext &ctx, Identifier id) {
_label("flags", _swiftInt),
_label("initialSerialExecutor", _defaulted(_optional(_executor), _nil)),
_label("taskGroup", _defaulted(_optional(_rawPointer), _nil)),
/*deprecated*/_label("initialTaskExecutor", _defaulted(_optional(_executor), _nil)),
/*deprecated*/_label("initialTaskExecutorConsuming", _defaulted(_consuming(_optional(_taskExecutor)), _nil)),
/* deprecated */_label("initialTaskExecutor", _defaulted(_optional(_executor), _nil)),
_label("initialTaskExecutorConsuming", _defaulted(_consuming(_optional(_taskExecutor)), _nil)),
_label("operation", _function(_async(_throws(_sendable(_thick))),
_void, _parameters()))),
_tuple(_nativeObject, _rawPointer));
Expand All @@ -1576,14 +1560,12 @@ static ValueDecl *getCreateAsyncTask(ASTContext &ctx, Identifier id,
unsigned numGenericParams = isDiscarding ? 0 : 1;
BuiltinFunctionBuilder builder(ctx, numGenericParams);
builder.addParameter(makeConcrete(ctx.getIntType())); // 0 flags

if (inGroup) {
builder.addParameter(makeConcrete(ctx.TheRawPointerType)); // group
}

if (withTaskExecutor) {
builder.addParameter(
makeConcrete(ctx.TheExecutorType)); // executor
builder.addParameter(makeConcrete(ctx.TheExecutorType)); // executor
}
auto extInfo = ASTExtInfoBuilder().withAsync().withThrows()
.withSendable(true).build();
Expand Down
8 changes: 5 additions & 3 deletions lib/IRGen/GenConcurrency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -686,15 +686,17 @@ struct InitialTaskExecutorOwnedRecordTraits {
->getCanonicalType();
}

// FIXME: this isn't quite right I guess; the taskExecutor is a pointer to the class so we need to get the identity and type...
void initialize(IRGenFunction &IGF, Address recordAddr,
Explosion &taskExecutor) const {
auto executorRecord =
IGF.Builder.CreateStructGEP(recordAddr, 1, 2 * IGF.IGM.getPointerSize());

// This relies on the fact that the HeapObject is directly followed by a
// pointer to the witness table.
IGF.Builder.CreateStore(taskExecutor.claimNext(),
IGF.Builder.CreateStructGEP(executorRecord, 0, Size()));
IGF.Builder.CreateStructGEP(executorRecord, 0, Size()));
IGF.Builder.CreateStore(taskExecutor.claimNext(),
IGF.Builder.CreateStructGEP(executorRecord, 1, Size()));
IGF.Builder.CreateStructGEP(executorRecord, 1, Size()));
}
};

Expand Down
4 changes: 0 additions & 4 deletions lib/IRGen/IRGenSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3617,10 +3617,6 @@ static void emitBuiltinStackDealloc(IRGenSILFunction &IGF,

static void emitBuiltinCreateAsyncTask(IRGenSILFunction &IGF,
swift::BuiltinInst *i) {
fprintf(stderr, "[%s:%d](%s) emitBuiltinCreateAsyncTask -> \n", __FILE_NAME__, __LINE__, __FUNCTION__);
i->dump();
i->dumpInContext();

assert(i->getOperandValues().size() == 6 &&
"createAsyncTask needs 6 operands");
auto flags = IGF.getLoweredSingletonExplosion(i->getOperand(0));
Expand Down
4 changes: 0 additions & 4 deletions lib/SIL/IR/OperandOwnership.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -930,10 +930,6 @@ OperandOwnershipBuiltinClassifier::visitCreateAsyncTask(BuiltinInst *bi,
if (&op == &bi->getOperandRef(4)) {
// The (any TaskExecutor)? (optional) must be consumed by the builtin,
// as we will keep it alive and later destroy it as the task runs to completion.
// fprintf(stderr, "[%s:%d](%s) MAKE DESTROYING CONSUME; bi:\n", __FILE_NAME__, __LINE__, __FUNCTION__);
// bi->dump();
// fprintf(stderr, "[%s:%d](%s) MAKE DESTROYING CONSUME; op: \n", __FILE_NAME__, __LINE__, __FUNCTION__);
// op.dump();
return OperandOwnership::ForwardingConsume;
}

Expand Down
24 changes: 8 additions & 16 deletions stdlib/public/Concurrency/Task+TaskExecutor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ extension Task where Failure == Never {
self = Self.init(priority: priority, operation: operation)
return
}
#if $BuiltinCreateAsyncTaskWithExecutor
#if $BuiltinCreateAsyncTaskWithExecutor && $BuiltinCreateTask
// Set up the job flags for a new task.
let flags = taskCreateFlags(
priority: priority, isChildTask: false, copyTaskLocals: true,
Expand All @@ -244,7 +244,7 @@ extension Task where Failure == Never {

self._task = task
#else
fatalError("Unsupported Swift compiler, missing support for BuiltinCreateAsyncTaskWithExecutor")
fatalError("Unsupported Swift compiler, missing support for BuiltinCreateAsyncTaskWithExecutor or $BuiltinCreateTask")
#endif
}
}
Expand Down Expand Up @@ -289,7 +289,7 @@ extension Task where Failure == Error {
self = Self.init(priority: priority, operation: operation)
return
}
#if $BuiltinCreateAsyncTaskWithExecutor
#if $BuiltinCreateAsyncTaskWithExecutor && $BuiltinCreateTask
// Set up the job flags for a new task.
let flags = taskCreateFlags(
priority: priority, isChildTask: false, copyTaskLocals: true,
Expand All @@ -304,7 +304,7 @@ extension Task where Failure == Error {

self._task = task
#else
fatalError("Unsupported Swift compiler, missing support for $BuiltinCreateAsyncTaskWithExecutor")
fatalError("Unsupported Swift compiler, missing support for BuiltinCreateAsyncTaskWithExecutor or $BuiltinCreateTask")
#endif
}
}
Expand Down Expand Up @@ -347,7 +347,7 @@ extension Task where Failure == Never {
guard let taskExecutor else {
return Self.detached(priority: priority, operation: operation)
}
#if $BuiltinCreateAsyncTaskWithExecutor
#if $BuiltinCreateAsyncTaskWithExecutor && $BuiltinCreateTask
// Set up the job flags for a new task.
let flags = taskCreateFlags(
priority: priority, isChildTask: false, copyTaskLocals: false,
Expand All @@ -363,7 +363,7 @@ extension Task where Failure == Never {

return Task(task)
#else
fatalError("Unsupported Swift compiler")
fatalError("Unsupported Swift compiler, missing support for BuiltinCreateAsyncTaskWithExecutor or $BuiltinCreateTask")
#endif
}
}
Expand Down Expand Up @@ -406,30 +406,22 @@ extension Task where Failure == Error {
guard let taskExecutor else {
return Self.detached(priority: priority, operation: operation)
}
#if $BuiltinCreateAsyncTaskWithExecutor
#if $BuiltinCreateAsyncTaskWithExecutor && $BuiltinCreateTask
// Set up the job flags for a new task.
let flags = taskCreateFlags(
priority: priority, isChildTask: false, copyTaskLocals: false,
inheritContext: false, enqueueJob: true,
addPendingGroupTaskUnconditionally: false,
isDiscardingTask: false)

// Create the asynchronous task.
// let executorBuiltin: Builtin.Executor =
// taskExecutor.asUnownedTaskExecutor().executor

// LEGACY:
// let (task, _) = Builtin.createAsyncTaskWithExecutor(
// flags, executorBuiltin, operation)
let (task, _) = Builtin.createTask(
flags: flags,
// initialTaskExecutor: executorBuiltin, deprecated
initialTaskExecutorConsuming: taskExecutor,
operation: operation)

return Task(task)
#else
fatalError("Unsupported Swift compiler")
fatalError("Unsupported Swift compiler, missing support for BuiltinCreateAsyncTaskWithExecutor or $BuiltinCreateTask")
#endif
}
}
Expand Down
17 changes: 1 addition & 16 deletions stdlib/public/Concurrency/Task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,21 +205,10 @@ TaskExecutorRef _task_taskExecutor_getTaskExecutorRef(

TaskExecutorRef
InitialTaskExecutorOwnedPreferenceTaskOptionRecord::getExecutorRefFromUnownedTaskExecutor() const {
fprintf(stderr, "[%s:%d](%s) we must call into the SerialExecutor::asUnownedTaskExecutor()\n", __FILE_NAME__, __LINE__, __FUNCTION__);
fprintf(stderr, "[%s:%d](%s) the executor Identity = %p\n", __FILE_NAME__, __LINE__, __FUNCTION__,
Identity);
fprintf(stderr, "[%s:%d](%s) the executor WitnessT = %p\n", __FILE_NAME__, __LINE__, __FUNCTION__,
WitnessTable);

TaskExecutorRef executorRef = _task_taskExecutor_getTaskExecutorRef(
Identity,
/*selfType=*/swift_getObjectType(Identity),
/*wtable=*/WitnessTable);

fprintf(stderr, "[%s:%d](%s) got executor ref: ident = %p\n", __FILE_NAME__, __LINE__, __FUNCTION__,
executorRef.getIdentity());
fprintf(stderr, "[%s:%d](%s) got executor ref: raw impl = %p\n", __FILE_NAME__, __LINE__, __FUNCTION__,
executorRef.getRawImplementation());
return executorRef;
}

Expand Down Expand Up @@ -696,18 +685,14 @@ swift_task_create_commonImpl(size_t rawTaskCreateFlags,
break;

case TaskOptionRecordKind::InitialTaskExecutorUnowned:
fprintf(stderr, "[%s:%d](%s) TASK EXECUTOR UNOWNED GET THE RECORD...\n", __FILE_NAME__, __LINE__, __FUNCTION__);
taskExecutor = cast<InitialTaskExecutorPreferenceTaskOptionRecord>(option)
taskExecutor = cast<InitialTaskExecutorRefPreferenceTaskOptionRecord>(option)
->getExecutorRef();
jobFlags.task_setHasInitialTaskExecutorPreference(true);
break;

case TaskOptionRecordKind::InitialTaskExecutorOwned:
taskExecutor = cast<InitialTaskExecutorOwnedPreferenceTaskOptionRecord>(option)
->getExecutorRefFromUnownedTaskExecutor();
fprintf(stderr, "[%s:%d](%s) EMIT OWNED: %p | %p\n", __FILE_NAME__, __LINE__, __FUNCTION__,
taskExecutor.getIdentity(),
taskExecutor.getRawImplementation());
jobFlags.task_setHasInitialTaskExecutorPreference(true);
break;

Expand Down
Loading

0 comments on commit 707551e

Please sign in to comment.