quick-and-dirty implementation of MainActor in the runtime system

it is "dirty" in the sense that we don't have proper support for
custom executors right now.
This commit is contained in:
Kavon Farvardin
2021-01-08 17:48:08 -08:00
parent 10160cbff9
commit 91e2246c19
6 changed files with 100 additions and 23 deletions

View File

@@ -19,6 +19,7 @@
#include <inttypes.h>
#include "swift/ABI/HeapObject.h"
#include "swift/Runtime/Casting.h"
namespace swift {
class AsyncContext;
@@ -26,6 +27,10 @@ class AsyncTask;
class DefaultActor;
class Job;
/// FIXME: only exists for the quick-and-dirty MainActor implementation.
SWIFT_EXPORT_FROM(swift_Concurrency)
Metadata* MainActorMetadata;
/// An ExecutorRef isn't necessarily just a pointer to an executor
/// object; it may have other bits set.
class ExecutorRef {
@@ -45,6 +50,13 @@ public:
return ExecutorRef(0);
}
/// FIXME: only exists for the quick-and-dirty MainActor implementation.
/// NOTE: I didn't go with Executor::forMainActor(DefaultActor*) because
/// __swift_run_job_main_executor can't take more than one argument.
constexpr static ExecutorRef mainExecutor() {
return ExecutorRef(2);
}
/// Given a pointer to a default actor, return an executor reference
/// for it.
static ExecutorRef forDefaultActor(DefaultActor *actor) {
@@ -57,6 +69,20 @@ public:
return Value == 0;
}
/// FIXME: only exists for the quick-and-dirty MainActor implementation.
bool isMainExecutor() const {
if (Value == ExecutorRef::mainExecutor().Value)
return true;
HeapObject *heapObj = reinterpret_cast<HeapObject*>(Value & ~PointerMask);
if (heapObj == nullptr || MainActorMetadata == nullptr)
return false;
Metadata const* metadata = swift_getObjectType(heapObj);
return metadata == MainActorMetadata;
}
/// Is this a default-actor executor reference?
bool isDefaultActor() const {
return Value & IsDefaultActor;
@@ -77,10 +103,12 @@ public:
}
bool operator==(ExecutorRef other) const {
return Value == other.Value;
return Value == other.Value
/// FIXME: only exists for the quick-and-dirty MainActor implementation.
|| (isMainExecutor() && other.isMainExecutor());
}
bool operator!=(ExecutorRef other) const {
return Value != other.Value;
return !(*this == other);
}
};