Skip to main content

logicaffeine_compile/concurrency/
mod.rs

1//! Concurrency determinacy model + classifier (Phase 0 of `work/FINISH_INTERPRETER.md`).
2//!
3//! This module is the single source of truth for the language's concurrency
4//! *memory model* and the *determinacy classifier* that labels a program as
5//! belonging to the determinate (Kahn-deterministic) or nondeterminate fragment.
6//! The classifier is consumed by AOT mode selection (Phase 8) and translation
7//! validation (Phase 11), so both agree on one boundary.
8
9pub mod bridge;
10pub mod driver;
11pub mod vm_driver;
12pub mod channel;
13pub mod classify;
14pub mod fec;
15pub mod marshal;
16pub mod model;
17pub(crate) mod net_inbox;
18pub mod pnp;
19pub mod send_check;
20pub mod stream;
21
22use crate::ast::stmt::Stmt;
23
24/// Does the program use Go-like concurrency (channels / tasks / select) that must
25/// run on the scheduler-driven interpreter path?
26pub fn uses_scheduler(stmts: &[Stmt]) -> bool {
27    stmts.iter().any(stmt_uses_scheduler)
28}
29
30fn stmt_uses_scheduler(s: &Stmt) -> bool {
31    match s {
32        Stmt::LaunchTask { .. }
33        | Stmt::LaunchTaskWithHandle { .. }
34        | Stmt::CreatePipe { .. }
35        | Stmt::SendPipe { .. }
36        | Stmt::ReceivePipe { .. }
37        | Stmt::TrySendPipe { .. }
38        | Stmt::TryReceivePipe { .. }
39        | Stmt::Select { .. }
40        | Stmt::StopTask { .. } => true,
41        Stmt::If { then_block, else_block, .. } => {
42            then_block.iter().any(stmt_uses_scheduler)
43                || else_block.map_or(false, |b| b.iter().any(stmt_uses_scheduler))
44        }
45        Stmt::While { body, .. }
46        | Stmt::Repeat { body, .. }
47        | Stmt::Zone { body, .. }
48        | Stmt::FunctionDef { body, .. } => body.iter().any(stmt_uses_scheduler),
49        Stmt::Concurrent { tasks } | Stmt::Parallel { tasks } => {
50            tasks.iter().any(stmt_uses_scheduler)
51        }
52        Stmt::Inspect { arms, .. } => {
53            arms.iter().any(|a| a.body.iter().any(stmt_uses_scheduler))
54        }
55        _ => false,
56    }
57}
58
59pub use classify::{branches_independent, branches_share_mutable_state, classify_program};
60pub use marshal::{materialize, rebuild, MarshalError};
61pub use model::{Determinacy, NondetKind, NondetWitness};
62pub use net_inbox::{net_is_offline, set_net_offline};
63pub use send_check::{check_send_escape, SendDiagnostic};