Runtime support for isolated deinit

This commit is contained in:
Mykola Pokhylets
2022-06-13 12:06:50 +02:00
parent de9aefc842
commit b7e23c2e2e
9 changed files with 83 additions and 3 deletions

View File

@@ -291,6 +291,7 @@ using ThrowingTaskFutureWaitContinuationFunction =
SWIFT_CC(swiftasync)
void (SWIFT_ASYNC_CONTEXT AsyncContext *, SWIFT_CONTEXT void *);
using AdHocWorkFunction = SWIFT_CC(swift) void(void *);
template <class AsyncSignature>
class AsyncFunctionPointer;

View File

@@ -2490,7 +2490,8 @@ enum class JobKind : size_t {
DefaultActorInline = First_Reserved,
DefaultActorSeparate,
DefaultActorOverride,
NullaryContinuation
NullaryContinuation,
AdHoc,
};
/// The priority of a job. Higher priorities are larger values.

View File

@@ -186,6 +186,27 @@ public:
}
};
/// Job that allows to use executor API to schedule a block of task-less
/// synchronous code.
class AdHocJob : public Job {
private:
void *Context;
AdHocWorkFunction *Work;
public:
AdHocJob(JobPriority priority, void *context, AdHocWorkFunction *work)
: Job({JobKind::AdHoc, priority}, &process), Context(context),
Work(work) {}
SWIFT_CC(swiftasync)
static void process(Job *job);
static bool classof(const Job *job) {
return job->Flags.getKind() == JobKind::AdHoc;
}
};
/// Describes type information and offers value methods for an arbitrary concrete
/// type in a way that's compatible with regular Swift and embedded Swift. In
/// regular Swift, just holds a Metadata pointer and dispatches to the value

View File

@@ -605,6 +605,11 @@ swift_task_createNullaryContinuationJob(
size_t priority,
AsyncTask *continuation);
SWIFT_EXPORT_FROM(swift_Concurrency)
SWIFT_CC(swift)
void swift_task_performOnExecutor(void *context, AdHocWorkFunction *work,
SerialExecutorRef newExecutor);
/// Report error about attempting to bind a task-local value from an illegal context.
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
void swift_task_reportIllegalTaskLocalBindingWithinWithTaskGroup(

View File

@@ -2263,7 +2263,7 @@ FUNCTION(GetTypeByMangledNameInContextInMetadataState2,
EFFECT(MetaData),
MEMEFFECTS(ArgMemOnly))
// AsyncTask *swift_task_getCurrent();s
// AsyncTask *swift_task_getCurrent();
FUNCTION(GetCurrentTask,
swift_task_getCurrent, SwiftCC,
ConcurrencyAvailability,
@@ -2332,6 +2332,19 @@ FUNCTION(TaskSwitchFunc,
ATTRS(NoUnwind),
EFFECT(Concurrency),
UNKNOWN_MEMEFFECTS)
// void swift_task_performOnExecutor(void *context,
// AdHocWorkFunction *work,
// SerialExecutorRef newExecutor);
FUNCTION(PerformOnExecutorFunc,
swift_task_performOnExecutor, SwiftCC,
ConcurrencyAvailability,
RETURNS(VoidTy),
ARGS(Int8PtrTy, Int8PtrTy, ExecutorFirstTy, ExecutorSecondTy),
ATTRS(NoUnwind),
EFFECT(Concurrency),
UNKNOWN_MEMEFFECTS)
// AsyncTask *swift_continuation_init(AsyncContext *continuationContext,
// AsyncContinuationFlags);

View File

@@ -200,6 +200,11 @@ OVERRIDE_TASK(task_createNullaryContinuationJob, NullaryContinuationJob *,
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift), swift::,
(size_t priority,
AsyncTask *continuation), (priority, continuation))
OVERRIDE_TASK(task_performOnExecutor, void,
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift), swift::,
(void *context, AdHocWorkFunction *work, SerialExecutorRef newExecutor),
(context, work, newExecutor))
HOOKED_OVERRIDE_TASK_NORETURN(task_asyncMainDrainQueue,
SWIFT_EXPORT_FROM(swift_Concurrency), SWIFT_CC(swift),

View File

@@ -206,6 +206,14 @@ void NullaryContinuationJob::process(Job *_job) {
swift_continuation_resume(continuation);
}
void AdHocJob::process(Job *_job) {
auto *job = cast<AdHocJob>(_job);
void *ctx = job->Context;
AdHocWorkFunction *work = job->Work;
delete job;
return work(ctx);
}
void AsyncTask::completeFuture(AsyncContext *context) {
using Status = FutureFragment::Status;
using WaitQueueItem = FutureFragment::WaitQueueItem;
@@ -1674,6 +1682,27 @@ swift_task_createNullaryContinuationJobImpl(
return job;
}
SWIFT_CC(swift)
static void swift_task_performOnExecutorImpl(void *context,
AdHocWorkFunction *work,
SerialExecutorRef newExecutor) {
auto currentExecutor = swift_task_getCurrentExecutor();
// If the current executor is compatible with running the new executor,
// we can just immediately continue running with the resume function
// we were passed in.
if (!currentExecutor.mustSwitchToRun(newExecutor)) {
return work(context); // 'return' forces tail call
}
auto currentTask = swift_task_getCurrent();
auto priority = currentTask ? swift_task_currentPriority(currentTask)
: swift_task_getCurrentThreadPriority();
auto job = new AdHocJob(priority, context, work);
swift_task_enqueue(job, newExecutor);
}
SWIFT_CC(swift)
void swift::swift_continuation_logFailedCheck(const char *message) {
swift_reportError(0, message);

View File

@@ -320,3 +320,5 @@ Added: _$ss9TaskLocalC13withValueImpl_9operation9isolation4file4lineqd__xn_qd__y
Added: _$ss9TaskLocalC9withValue_9operation9isolation4file4lineqd__x_qd__yYaKXEScA_pSgYiSSSutYaKlF
Added: _$ss9TaskLocalC9withValue_9operation9isolation4file4lineqd__x_qd__yYaKXEScA_pSgYiSSSutYaKlFTu
// isolated deinit
Added: _swift_task_performOnExecutor

View File

@@ -318,4 +318,7 @@ Added: _$ss9TaskLocalC13withValueImpl_9operation9isolation4file4lineqd__xn_qd__y
Added: _$ss9TaskLocalC13withValueImpl_9operation9isolation4file4lineqd__xn_qd__yYaKXEScA_pSgYiSSSutYaKlFTu
// Swift.TaskLocal.withValue<A>(_: A, operation: () async throws -> A1, isolation: isolated Swift.Actor?, file: Swift.String, line: Swift.UInt) async throws -> A1
Added: _$ss9TaskLocalC9withValue_9operation9isolation4file4lineqd__x_qd__yYaKXEScA_pSgYiSSSutYaKlF
Added: _$ss9TaskLocalC9withValue_9operation9isolation4file4lineqd__x_qd__yYaKXEScA_pSgYiSSSutYaKlFTu
Added: _$ss9TaskLocalC9withValue_9operation9isolation4file4lineqd__x_qd__yYaKXEScA_pSgYiSSSutYaKlFTu
// isolated deinit
Added: _swift_task_performOnExecutor