Hi everyone,
I'm very happy to be able to share with the forums a talk we did about adoption of Swift / C++ interop in FoundationDB.
This work already was mentioned a little bit during WWDC23, but this is a full deep dive into how the C++ interop was utilized and the problems it aims to solve in the project.
It's a great testament to how far the C++ interop has already gotten, even at its early stages.
I also want to extend a shout out here to @Alex_L, @zoecarver and @etcwilde who were all instrumental to the work being shown in this presentation.
The section on actor runtime interoperability went by very quickly… can you elaborate on that? If I heard correctly, it sounds like FDB found & utilises some way to have Swift's Structured Concurrency primitives (Task, TaskGroup, etc) actually map to C++ code instead of the native Swift runtime…?
The Swift concurrency runtime has a hook called swift_task_enqueueGlobal_hook which some libraries (like async-algorithms) use for testing; It takes over all enqueues made by the concurrency runtime. In FDB this is exactly what we need, since all tasks must be enqueued on FDB's event loop.
The implementation FDB is simple:
void sim2_enqueueGlobal_hook_impl(swift::Job* _Nonnull job, void (*_Nonnull)(swift::Job*) __attribute__((swiftcall))) {
ISimulator* sim = g_simulator;
sim->_swiftEnqueue(job);
}
// installing the hook:
// swift_task_enqueueGlobal_hook = sim2_enqueueGlobal_hook_impl
void _swiftEnqueue(void* _job) override {
ASSERT(getCurrentProcess());
swift::Job* job = (swift::Job*)_job; // Swift runtime type
...
auto t = new PromiseTask(machine, job); // FDB runtime type
taskQueue.addReady(priority, t); // FDB event loop
}
and the FDB eventloop gained:
if (t.swiftJob) {
// swift logic
swift_job_run(t.swiftJob, ExecutorRef::generic());
} else {
t.promise.send(Void()); // normal logic
}
and that's pretty much it.
The hook can be used with Swift functions as well, as async-algorithms do -- but really it is only for taking over all scheduling -- and in most cases people should rather use custom executors.