Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 2 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ members = [
"sdk/std/copies",
"sdk/osrelease",
"sdk/toyos",
"sdk/transport",
"sdk/window",
"system/acpiserver",
"system/acpiserver/aml",
Expand Down
18 changes: 13 additions & 5 deletions build/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2724,23 +2724,27 @@ mod tests {
"test-actuators",
];

/// Features of a host workspace member that choose a build's world rather
/// Features of a host-tested member that choose a build's world rather
/// than revert a decision: loom's atomics, a crate's `std` and its default
/// set, the toolchain's `core` and `rustc-dep-of-std`, libc's `std-runtime`,
/// the signer's `sign`, `flaws`, which compiles what a simulator's
/// negative gates select at run time, and `toyos-crypto`'s `portable`,
/// `wpa2` and `rustls-provider`, which `--ci host` tests as forms of its own.
/// negative gates select at run time, `toyos-crypto`'s `portable`, `wpa2`
/// and `rustls-provider`, which `--ci host` tests as forms of its own, and
/// of the guest libraries, `toyos-font`'s `ttf`, its TrueType rendering,
/// and `toyos-pci-claim`'s `host-grant`, which netstack's host tests build.
const NOT_A_CONTROL: &[&str] = &[
"core",
"default",
"flaws",
"host-grant",
"loom",
"portable",
"rustc-dep-of-std",
"rustls-provider",
"sign",
"std",
"std-runtime",
"ttf",
"wpa2",
];

Expand Down Expand Up @@ -2799,7 +2803,8 @@ mod tests {

/// Every negative control the tree declares: every feature of the kernel's
/// manifest but its builds and [`KERNEL_CARRIES`], and every feature of every
/// host workspace member's but [`NOT_A_CONTROL`].
/// host workspace member's and guest library's (`hostws::GUEST_LIBRARIES`,
/// which a host tests too) but [`NOT_A_CONTROL`].
///
/// **Every manifest, and no list of the crates that hold a model.** A model
/// of memory orderings, of the process table's interleavings, of a simulated
Expand All @@ -2809,7 +2814,10 @@ mod tests {
/// Each file's own comment beside a name carries the argument for it.
fn declared_model_controls(root: &Path) -> BTreeSet<String> {
let mut out = BTreeSet::new();
for dir in std::iter::once(crate::ci::KERNEL_DIR.to_string()).chain(crate::hostws::host_members(root)) {
let host_tested = crate::hostws::host_members(root)
.into_iter()
.chain(crate::hostws::GUEST_LIBRARIES.map(String::from));
for dir in std::iter::once(crate::ci::KERNEL_DIR.to_string()).chain(host_tested) {
let path = root.join(&dir).join("Cargo.toml");
let text = fs::read_to_string(&path)
.unwrap_or_else(|e| panic!("Failed to read {}: {e}", path.display()));
Expand Down
31 changes: 16 additions & 15 deletions build/ci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,8 @@ pub(crate) const SDK_DIR: &str = "sdk/toyos";
const KERNEL_LOOM: &str = "kernel-loom";
const KERNEL_SIM: &str = "kernel-sim";
const BLOCKRING: &str = "toyos-blockring";
const TRANSPORT: &str = "toyos-transport";
/// The SDK package, whose `transport` module carries its own controls.
const SDK: &str = "toyos";

/// `toyos-crypto`, tested and linted in each of [`CRYPTO_FORMS`] rather than
/// with the features the workspace's other members unify onto it.
Expand Down Expand Up @@ -692,20 +693,20 @@ pub(crate) const CONTROLS: &[Control] = &[
red(BLOCKRING, "mutate-no-reissue-after-loss", None, &[
Fails("model::tests::what_a_flush_calls_durable_is_on_the_medium"),
]),
red(TRANSPORT, "publish-relaxed", Some("loom"), &[
red(SDK, "transport-publish-relaxed", Some("transport_loom"), &[
Fails("a_published_entry_is_read_whole"),
Fails("a_published_byte_is_read_as_written"),
]),
red(TRANSPORT, "head-relaxed", Some("loom"), &[Fails("a_published_byte_is_read_as_written")]),
red(TRANSPORT, "no-clamp", Some("loom"), &[Fails(
red(SDK, "transport-head-relaxed", Some("transport_loom"), &[Fails("a_published_byte_is_read_as_written")]),
red(SDK, "transport-no-clamp", Some("transport_loom"), &[Fails(
"a_hostile_producer_yields_entries_or_a_violation",
)]),
red(TRANSPORT, "no-clamp", None, &[Fails(
"stream::tests::a_hostile_producer_hands_the_consumer_at_most_the_ring",
red(SDK, "transport-no-clamp", None, &[Fails(
"transport::stream::tests::a_hostile_producer_hands_the_consumer_at_most_the_ring",
)]),
// The stream's lost wake: a sleeper whose exchange read the waker's clear
// looks at a cursor from before it, and sleeps with nobody to ring.
red(TRANSPORT, "want-relaxed", Some("loom"), &[
red(SDK, "transport-want-relaxed", Some("transport_loom"), &[
Fails("a_consumer_that_looked_again_is_rung_for_bytes_it_missed"),
Fails("a_producer_that_looked_again_is_rung_for_room_it_missed"),
Fails("two_sleepers_each_wake_when_room_is_released_first"),
Expand All @@ -721,24 +722,24 @@ pub(crate) const CONTROLS: &[Control] = &[
// A session's lost wakes: a reader and a writer on one doorbell, a take
// not passed on, a registration that neither arms nor rings, and a reset
// a look that arms does not see.
red(TRANSPORT, "one-doorbell", Some("loom"), &[
red(SDK, "transport-one-doorbell", Some("transport_loom"), &[
Fails("two_sleepers_each_wake_when_room_is_released_first"),
Fails("two_sleepers_each_wake_when_data_is_published_first"),
]),
red(TRANSPORT, "no-pass-on", Some("loom"), &[
red(SDK, "transport-no-pass-on", Some("transport_loom"), &[
Fails("a_poll_beside_a_blocking_read_is_answered_for_the_bytes_it_left"),
Fails("a_poll_beside_a_blocking_read_is_answered_for_the_end_it_left"),
Fails("a_poll_beside_a_blocking_write_is_answered_for_the_room_it_left"),
]),
red(TRANSPORT, "register-no-arm", Some("loom"), REGISTERED),
red(TRANSPORT, "register-no-ring", Some("loom"), REGISTERED),
red(TRANSPORT, "register-neither", Some("loom"), REGISTERED),
red(TRANSPORT, "head-only", Some("loom"), &[
red(SDK, "transport-register-no-arm", Some("transport_loom"), REGISTERED),
red(SDK, "transport-register-no-ring", Some("transport_loom"), REGISTERED),
red(SDK, "transport-register-neither", Some("transport_loom"), REGISTERED),
red(SDK, "transport-head-only", Some("transport_loom"), &[
Fails("a_source_registered_over_a_full_ring_after_a_reset_gets_its_first_event"),
Fails("a_source_registered_over_a_full_ring_as_a_reset_arrives_gets_its_first_event"),
]),
red(TRANSPORT, "end-keeps-inflight", None, &[Fails(
"inflight::tests::an_end_answers_every_tag_once_and_a_late_completion_nothing",
red(SDK, "transport-end-keeps-inflight", None, &[Fails(
"transport::inflight::tests::an_end_answers_every_tag_once_and_a_late_completion_nothing",
)]),
];

Expand Down
15 changes: 11 additions & 4 deletions build/clippy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,10 @@ const SHAPES: &[Shape] = &[
before: &["-p", CRYPTO, "--all-targets"],
after: &["$ADOPTED", "-D", "warnings"],
},
// `--no-deps` because its dependency `toyos` is a guest crate no shape
// lints. Its own target directory because `--no-deps` checks without clippy
// the host crates the workspace shapes lint, which `toyos-abi`'s shape
// below says costs every run.
// `--no-deps` because its dependency `toyos` is a guest crate, linted by
// the shapes that build it. Its own target directory because `--no-deps`
// checks without clippy the host crates the workspace shapes lint, which
// `toyos-abi`'s shape below says costs every run.
Shape {
before: &[
"-p",
Expand Down Expand Up @@ -208,6 +208,13 @@ const SHAPES: &[Shape] = &[
],
after: &["$ADOPTED", "-D", "warnings"],
},
// `toyos`'s tests, its transport's loom models among them: the workspace
// shapes exclude it and lint its library only as their members'
// dependency.
Shape {
before: &["-p", "toyos", "--all-targets"],
after: &["$ADOPTED", "-D", "warnings"],
},
// Its own target directory: cargo keeps one check of a unit, so a unit
// linted under two sets of lints is checked again by each, every run, and
// so is every crate depending on it.
Expand Down
7 changes: 3 additions & 4 deletions build/hostws.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,9 @@ pub(crate) fn rel(root: &Path, path: &Path) -> String {
}

/// The library members built for a guest: the SDK, its window, font and
/// file-picker clients and the two shared crates that link the SDK, whose
/// `toyos` is not clippy-clean on a host. Their tests run in a step of their
/// own ([`guest_libraries`]).
const GUEST_LIBRARIES: [&str; 6] = [
/// file-picker clients and the two shared crates that link the SDK. Their
/// tests run in a step of their own ([`guest_libraries`]).
pub(crate) const GUEST_LIBRARIES: [&str; 6] = [
crate::ci::SDK_DIR,
"sdk/window",
"sdk/font",
Expand Down
4 changes: 3 additions & 1 deletion build/sdkversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ pub struct Crate {
}

/// The published crates, in the order a publisher must take them.
///
/// A crate joins only once crates.io holds it with `publish.yml` its trusted
/// publisher: the token that workflow publishes with cannot create a crate.
pub const PUBLISHED: &[Crate] = &[
Crate { name: "toyos-abi", dir: "sdk/abi" },
Crate { name: "toyos-transport", dir: "sdk/transport" },
Crate { name: "toyos-keymap", dir: "sdk/keymap" },
Crate { name: "toyos-font", dir: "sdk/font" },
Crate { name: "toyos", dir: "sdk/toyos" },
Expand Down
18 changes: 7 additions & 11 deletions build/sysroot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,12 @@ use crate::toolchain::{self, host_triple, GuestTarget, Owner, Role, GUEST_TARGET
use whole_toolchain::{whole, Whole};

/// The per-worktree sources that end up inside a sysroot: std links the
/// `toyos-abi`, `toyos` and `toyos-transport` [`std_patch`] hands it and
/// compiles its ToyOS backend from `sdk/std`, and `libtoyos_c.a` is `sdk/libc`
/// with `toyos-elf` and `toyos-osrelease`.
pub const SYSROOT_SOURCES: [&str; 8] = [
/// `toyos-abi` and `toyos` [`std_patch`] hands it and compiles its ToyOS
/// backend from `sdk/std`, and `libtoyos_c.a` is `sdk/libc` with `toyos-elf`
/// and `toyos-osrelease`.
pub const SYSROOT_SOURCES: [&str; 7] = [
"sdk/abi/src",
"sdk/toyos/src",
"sdk/transport/src",
"sdk/std",
"lib/elf/src",
"sdk/osrelease/src",
Expand All @@ -81,10 +80,9 @@ pub const SYSROOT_SOURCES: [&str; 8] = [

/// Their manifests, and the lockfile and cargo configuration libc is built
/// under: the features, versions and flags of the same build.
pub(crate) const SYSROOT_MANIFESTS: [&str; 8] = [
pub(crate) const SYSROOT_MANIFESTS: [&str; 7] = [
"sdk/abi/Cargo.toml",
"sdk/toyos/Cargo.toml",
"sdk/transport/Cargo.toml",
"lib/elf/Cargo.toml",
"sdk/osrelease/Cargo.toml",
"sdk/libc/Cargo.toml",
Expand All @@ -95,7 +93,7 @@ pub(crate) const SYSROOT_MANIFESTS: [&str; 8] = [
/// Of [`SYSROOT_MANIFESTS`], the crates std names by version, which std's
/// lockfile resolves with the fork's own through [`std_patch`]: what of a
/// worktree can move a freestanding target's dependency versions.
const STD_MANIFESTS: [&str; 3] = ["sdk/abi/Cargo.toml", "sdk/toyos/Cargo.toml", "sdk/transport/Cargo.toml"];
const STD_MANIFESTS: [&str; 2] = ["sdk/abi/Cargo.toml", "sdk/toyos/Cargo.toml"];

/// One of the crates std names by version, in a worktree.
pub(crate) struct StdCrate {
Expand Down Expand Up @@ -1276,7 +1274,7 @@ pub(crate) mod tests {
/// The manifests [`std_crates`] reads, in a worktree at `root` that has
/// no other source: what a bootstrap run is handed std's patch from.
pub(crate) fn std_manifests(root: &Path) {
for (manifest, name) in STD_MANIFESTS.into_iter().zip(["toyos-abi", "toyos", "toyos-transport"]) {
for (manifest, name) in STD_MANIFESTS.into_iter().zip(["toyos-abi", "toyos"]) {
write(&root.join(manifest), &format!("[package]\nname = \"{name}\"\n"));
}
}
Expand Down Expand Up @@ -1317,8 +1315,6 @@ pub(crate) mod tests {
format!("patch.crates-io.toyos-abi.path=\"{at}/sdk/abi\""),
"--config".to_string(),
format!("patch.crates-io.toyos.path=\"{at}/sdk/toyos\""),
"--config".to_string(),
format!("patch.crates-io.toyos-transport.path=\"{at}/sdk/transport\""),
],
);
for name in ["work tree", "work\"tree", "work\\tree", "work\ttree"] {
Expand Down
3 changes: 1 addition & 2 deletions build/toolchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -825,9 +825,8 @@ mod tests {
let registry = |name: &str, version: &str| {
format!("/home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/{name}-{version}/src/lib.rs")
};
let rest = ours("sdk/transport");
let built_from = |abi: &str, toyos: &str| {
fs::write(built.join("dist/libstd.d"), format!("{}/dist/libstd.rlib: {abi} {toyos} {rest}\n", built.display()))
fs::write(built.join("dist/libstd.d"), format!("{}/dist/libstd.rlib: {abi} {toyos}\n", built.display()))
.unwrap();
std::panic::catch_unwind(|| assert_std_built_from(&root, &built))
.err()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ crate's doc-tests green:
| case | names | `cargo test -p <crate> --doc` under `E0308` |
|---|---|---|
| `toyos_bootmap::DirectMapEnd` | `E0603` | EXIT=0 |
| `toyos_transport::Place`, three blocks | `E0080` | EXIT=0 |
| `toyos::transport::Place`, three blocks | `E0080` | EXIT=0 |

What does hold a case to its reason in this tree is the block beside it that
compiles (`system/netstack/wire/src/lib.rs`, `mod compile_fail`). `Place`'s three
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,14 @@ Only an account can create a crate, and only then can it name `publish.yml`
the crate's trusted publisher. Nothing before a landing tells that a crate it
adds to `PUBLISHED` is not on crates.io.

Owner: the owner's crates.io account for the first versions; `build/sdkversion.rs`
Owner: the orchestrator, for the runs after landing; `build/sdkversion.rs`
for the rule.

`toyos-untrusted` has since been removed from the tree and from `PUBLISHED`,
so `toyos-transport` is the one crate still owed.
Neither crate is owed any more: #965 removed `toyos-untrusted`, and the
transport is now the `toyos` SDK's `transport` module, so `PUBLISHED` names
only crates the crates.io index holds (checked 2026-10-21). Its doc comment
says a crate joins only once crates.io holds it with `publish.yml` its trusted
publisher. Nothing yet shows a green run.

**Exit**: `toyos-transport` is on crates.io, naming `publish.yml` its trusted
publisher; a `publish` run at main's tip and the next
nightly's `release` are green; and `PUBLISHED`'s doc comment says a crate joins
it only once crates.io holds it under that publisher.
**Exit**: a `publish` run at main's tip after the transport merge lands, and
the next nightly's `release`, are green.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ a_consumer_that_looked_again_is_rung_for_bytes_it_missed --exact` kills the
test binary with SIGABRT, `panic in a destructor during cleanup`, through
`<loom::sync::arc::Arc<Stream> as Drop>::drop` and `rt::arc::Arc::ref_dec`.
On std's `Arc` the same run prints the test's `FAILED` line and loom's
`deadlock; threads = ...`.
`deadlock; threads = ...`. That model is now `sdk/toyos/tests/transport_loom.rs`,
its control `transport-want-relaxed` of `toyos`.

**Owner**: the orchestrator. Nobody holds it.

Expand Down
6 changes: 3 additions & 3 deletions issues/netstack-moves-every-byte-through-two-kernel-pipes.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ The design and its roast are PR #863's body.
`DeviceMemory`, and a receiver judges a lent region through `fstat` before
it maps it.
- Stage 2, done (PR #878): a byte ring with untrusted cursors and want words
in `toyos-transport` (`sdk/transport`), host-tested and modelled
in the SDK's `toyos::transport` (`sdk/toyos/src/transport`), host-tested and modelled
in loom.
- Stage 3, done (PR #905): a TCP stream, connected or accepted, is one
region whose two rings are [tcp]'s buffers and the connection it was opened
Expand Down Expand Up @@ -112,15 +112,15 @@ The design and its roast are PR #863's body.
over a full send ring, each answers a refusal only netstack judges that
lands meanwhile; each is red when the look reads `pending` before it arms,
red when netstack exchanges the wants before it stores `pending`, and red
under `want-relaxed`, and the sender's is red when netstack rings only
under `transport-want-relaxed`, and the sender's is red when netstack rings only
`rx_data`. In the other, [udp]'s queue starts full and a datagram leaves
it as its own step, interleaved with netstack's looks, so netstack can find
a published record while the queue is full and hold it; a sender that
fills the send ring, beside a `recv_from` asleep on the connection, has
every record sent, in order, none refused. It is red when netstack refuses
a record at the full queue, red when it rings `tx_room` on the connection,
red when after the leave it waits for the client's next ring without
looking at the send ring again, and red under `want-relaxed`.
looking at the send ring again, and red under `transport-want-relaxed`.

Owner: the orchestrator, who stages it.

Expand Down
4 changes: 2 additions & 2 deletions issues/the-transport-heads-orderings-have-no-oracle.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ opened: 2026-09-27

A consumer stores its head `Release` after it has loaded the entries below it,
and a producer loads the head `Acquire` before it writes over them
(`sdk/transport/src/queue.rs`, `Consumer::release` and `Producer::space`).
(`sdk/toyos/src/transport/queue.rs`, `Consumer::release` and `Producer::space`).
No test reds if either is `Relaxed`: what the pair forbids is load buffering —
a consumer's load of an entry reading the producer's later overwrite — which
loom does not model, and every other test runs both ends on one thread. The
tail's edge has its control (`publish-relaxed`); the head's has none.
tail's edge has its control (`transport-publish-relaxed`); the head's has none.

**Exit condition.** A control that relaxes the head's two orderings, and a
model or a run on a weakly ordered CPU that goes red under it.
Loading