///|
/// Reactor backend profile descriptors for Lockwire.
///|
pub fn package_id() -> String {
"lockwire/reactor"
}
///|
pub(all) enum ReactorBackendKind {
ReactorSim
ReactorEpoll
ReactorIocp
ReactorThreadx
} derive(Eq, Debug)
///|
pub fn ReactorBackendKind::label(self : ReactorBackendKind) -> String {
match self {
ReactorSim => "reactor_sim"
ReactorEpoll => "reactor_epoll"
ReactorIocp => "reactor_iocp"
ReactorThreadx => "reactor_threadx"
}
}
///|
pub(all) enum ReactorBoundary {
ReactorDeterministic
ReactorHostReal
ReactorEmbeddedReal
} derive(Eq, Debug)
///|
pub fn ReactorBoundary::label(self : ReactorBoundary) -> String {
match self {
ReactorDeterministic => "deterministic"
ReactorHostReal => "host-real"
ReactorEmbeddedReal => "embedded-real"
}
}
///|
pub(all) struct ReactorBackendDescriptor {
id : String
kind : ReactorBackendKind
boundary : ReactorBoundary
profiles : Array[@os.CapabilityProfile]
requires_native : Bool
requires_c_ffi : Bool
requires_os_fd : Bool
requires_threadx : Bool
deterministic : Bool
live_runtime : Bool
package_path : String
reference_path : String
} derive(Eq, Debug)
///|
pub fn ReactorBackendDescriptor::supports_profile(
self : ReactorBackendDescriptor,
profile : @os.CapabilityProfile,
) -> Bool {
self.profiles.any(fn(item) { item == profile })
}
///|
pub fn ReactorBackendDescriptor::violates_wasm_boundary(
self : ReactorBackendDescriptor,
) -> Bool {
self.supports_profile(@os.ProfileSimWasm) &&
(
self.requires_native ||
self.requires_c_ffi ||
self.requires_os_fd ||
self.requires_threadx ||
self.live_runtime
)
}
///|
pub fn ReactorBackendDescriptor::is_real_only(
self : ReactorBackendDescriptor,
) -> Bool {
self.live_runtime ||
self.requires_native ||
self.requires_os_fd ||
self.requires_threadx
}
///|
pub(all) struct ReactorBackendReport {
catalog_count : Int
sim_backend_count : Int
sim_wasm_count : Int
deterministic_count : Int
native_real_count : Int
real_linux_count : Int
real_embedded_count : Int
os_fd_count : Int
c_ffi_count : Int
live_runtime_count : Int
threadx_count : Int
wasm_violation_count : Int
} derive(Eq, Debug)
///|
pub fn ReactorBackendReport::passes(self : ReactorBackendReport) -> Bool {
self.catalog_count == 4 &&
self.sim_backend_count == 1 &&
self.sim_wasm_count == 1 &&
self.deterministic_count == 1 &&
self.native_real_count == 1 &&
self.real_linux_count == 1 &&
self.real_embedded_count == 1 &&
self.os_fd_count == 2 &&
self.c_ffi_count == 2 &&
self.live_runtime_count == 3 &&
self.threadx_count == 1 &&
self.wasm_violation_count == 0
}
///|
pub fn reactor_backend_catalog() -> Array[ReactorBackendDescriptor] {
[
{
id: "reactor.sim",
kind: ReactorSim,
boundary: ReactorDeterministic,
profiles: [@os.ProfileSimNative, @os.ProfileSimWasm, @os.ProfileReplay],
requires_native: false,
requires_c_ffi: false,
requires_os_fd: false,
requires_threadx: false,
deterministic: true,
live_runtime: false,
package_path: "lockwire/reactor",
reference_path: "lockwire/scenario/scenario.mbt",
},
{
id: "reactor.epoll",
kind: ReactorEpoll,
boundary: ReactorHostReal,
profiles: [@os.ProfileRealLinux],
requires_native: true,
requires_c_ffi: true,
requires_os_fd: true,
requires_threadx: false,
deterministic: false,
live_runtime: true,
package_path: "lockwire/reactor/epoll",
reference_path: "docs/Isochronon-architecture.md#reactor_epoll",
},
{
id: "reactor.iocp",
kind: ReactorIocp,
boundary: ReactorHostReal,
profiles: [@os.ProfileNativeReal],
requires_native: true,
requires_c_ffi: true,
requires_os_fd: true,
requires_threadx: false,
deterministic: false,
live_runtime: true,
package_path: "lockwire/reactor/iocp",
reference_path: "docs/clock-layer.md#async",
},
{
id: "reactor.threadx",
kind: ReactorThreadx,
boundary: ReactorEmbeddedReal,
profiles: [@os.ProfileRealEmbedded],
requires_native: true,
requires_c_ffi: false,
requires_os_fd: false,
requires_threadx: true,
deterministic: false,
live_runtime: true,
package_path: "lockwire/reactor/threadx",
reference_path: "docs/clock-layer.md#threadx",
},
]
}
///|
pub fn reactor_backend_report() -> ReactorBackendReport {
let catalog = reactor_backend_catalog()
{
catalog_count: catalog.length(),
sim_backend_count: count_where(catalog, fn(item) { item.kind == ReactorSim }),
sim_wasm_count: count_profile(catalog, @os.ProfileSimWasm),
deterministic_count: count_where(catalog, fn(item) { item.deterministic }),
native_real_count: count_profile(catalog, @os.ProfileNativeReal),
real_linux_count: count_profile(catalog, @os.ProfileRealLinux),
real_embedded_count: count_profile(catalog, @os.ProfileRealEmbedded),
os_fd_count: count_where(catalog, fn(item) { item.requires_os_fd }),
c_ffi_count: count_where(catalog, fn(item) { item.requires_c_ffi }),
live_runtime_count: count_where(catalog, fn(item) { item.live_runtime }),
threadx_count: count_where(catalog, fn(item) { item.requires_threadx }),
wasm_violation_count: count_where(catalog, fn(item) {
item.violates_wasm_boundary()
}),
}
}
///|
fn count_profile(
catalog : ArrayView[ReactorBackendDescriptor],
profile : @os.CapabilityProfile,
) -> Int {
count_where(catalog, fn(item) { item.supports_profile(profile) })
}
///|
fn count_where(
catalog : ArrayView[ReactorBackendDescriptor],
predicate : (ReactorBackendDescriptor) -> Bool,
) -> Int {
let mut count = 0
for item in catalog {
if predicate(item) {
count += 1
}
}
count
}