Skip to content

Commit

Permalink
New list implementation.
Browse files Browse the repository at this point in the history
This replaces the five-year-old lilos::list module with a new
implementation derived from my "lilist" sketch. Compared to the
original, the new list has the following advantages:

- Its implementation is shorter.
- Its API is simpler.
- It no longer requires two-phase init, and so things using it _also_
  don't require two-phase init.
- It can be tested under Miri to catch pointer abuses.
- It's exposed as a separate crate, which means I can update it without
  having to rev the OS.
  • Loading branch information
cbiffle committed May 4, 2024
1 parent e130f5a commit 96c2788
Show file tree
Hide file tree
Showing 24 changed files with 1,159 additions and 360 deletions.
17 changes: 14 additions & 3 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[workspace]
resolver = "2"
members = [
"list",
"os",
"handoff",
"semaphore",
Expand All @@ -23,6 +24,7 @@ rust-version = "1.69"
[workspace.dependencies]
# Internal
lilos = { path = "os", version = "1.1.0", default-features = false }
lilos-list = { path = "list", version = "0.1.0" }
lilos-testsuite = { path = "testsuite" }
lilos-handoff = { path = "handoff" }
lilos-semaphore = { path = "semaphore" }
Expand Down
42 changes: 37 additions & 5 deletions RELEASE-NOTES.mkdn
Original file line number Diff line number Diff line change
@@ -1,14 +1,46 @@
# Release Notes

## Version 1.1.1 (in progress)
## Version 1.2.0 (in progress)

### Core API changes

- The original `list` module, and the `List` and `Node` types it contained, are
now deprecated. The new `lilos-list` crate provides a dramatically improved
version. In particular, this eliminates the need for the "two-phase init"
dance with pinned OS types that has haunted `lilos` from the early days.
- Uses of the old `List` type should use the new one from `lilos-list`.
- Instead of using macros to create a list, write: `pin!(List::new())`.
- The `Node` type is now private. Instead, the "contents" field that used to
be passed to `create_node!` is now a parameter to the `List::wait` function.

- Two-phase init of `Mutex` is now deprecated. You can now just write
`pin!(Mutex::create(something))`. (It's `create` and not `new` because I'm
preserving `new` in deprecated form for backwards compatibility with 1.1.) The
mutex creation macros still work.

- It is now possible to create a `Mutex` or `List` in a `const fn` context,
including in a static initializer.

### Non-Core API

- The `lilos-list` crate exists now.

- `rwlock` 0.2 uses the new `lilos-list` internally, and no longer requires (or
supports) two-phase init. I've removed the creation macro.

- `semaphore` 0.2 uses the new `lilos-list` internally, and no longer requires (or
supports) two-phase init. I've removed the creation macro here, too.

### Internal improvements

- All code using lists, particularly timer lists, should now be slightly
smaller.
- All internal use of lists has been rewritten to use `waitlist`.

- All code using any kind of lists, particularly timer lists, should now be
slightly smaller.

- Removed an internal unused `Waker` implementation, reducing the base flash
requirement of the OS.
- Removed an internal mostly-unused `Waker` implementation, reducing the base
flash requirement of the OS for applications that use the new `waitlist`
module.

- `spsc` now uses `get_unchecked` in a couple of places to avoid generating
bounds checks. This is the first place in `lilos` where I've used unsafe code
Expand Down
2 changes: 1 addition & 1 deletion build-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ for k in ${!MODES[@]}; do
popd > /dev/null
done

DIRS="handoff semaphore rwlock testsuite/stm32f4 testsuite/stm32g0 testsuite/stm32f3 testsuite/lm3s6965 examples/*/*/"
DIRS="handoff semaphore rwlock list testsuite/stm32f4 testsuite/stm32g0 testsuite/stm32f3 testsuite/lm3s6965 examples/*/*/"

for d in $DIRS; do
if [[ $d == *memory.x ]]; then
Expand Down
2 changes: 1 addition & 1 deletion clippy-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

set -euo pipefail

DIRS="os handoff semaphore rwlock testsuite/stm32f4 testsuite/stm32g0 testsuite/stm32f3 examples/*/*/"
DIRS="os list handoff semaphore rwlock testsuite/stm32f4 testsuite/stm32g0 testsuite/stm32f3 examples/*/*/"

for d in $DIRS; do
echo "---- clipping in $d"
Expand Down
16 changes: 16 additions & 0 deletions list/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "lilos-list"
version = "0.1.0"
authors = ["Cliff L. Biffle <code@cliffle.com>"]
description = "Allocation-free intrusive doubly-linked wait queues for lilos."
keywords = ["async", "embedded", "os"]
categories = ["embedded", "no-std"]
readme = "README.mkdn"

edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true

[dependencies]
pin-project.workspace = true
23 changes: 23 additions & 0 deletions list/README.mkdn
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Allocation-free doubly-linked intrusive lists

This is the list type used to implement timer lists and wait queues in
[`lilos`]. It takes an unusual approach to implementing a sound doubly-linked
intrusive list in Rust without allocation, which is otherwise quite difficult:
it presents a different API that's easier to make sound.

This data structure can be built for any platform, and has tests that can run
both hosted and under Miri (to check for pointer abuses).

See the rustdoc for more details.

## Versioning

It's not important for applications or custom synchronization primitives to use
_exactly_ the same version of `lilos-list` as `lilos` does internally. Having
multiple versions linked into a single binary will work fine. (However, it will
take somewhat less space in flash if you can arrange to use the same version.)

`lilos-list` is versioned separately from the OS API and will likely go through
major versions faster than the rest of the OS.

[`lilos`]: https://docs.rs/lilos/latest/lilos/
Loading

0 comments on commit 96c2788

Please sign in to comment.