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
16 changes: 10 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,29 @@ on:
- cron: '50 4 * * *'
workflow_dispatch:

env:
rust_toolchain: nightly

jobs:
compile:
name: Compile
runs-on: ubuntu-latest

strategy:
matrix:
rust_toolchain:
- nightly
- 1.83 # MSRV

steps:
- name: Setup | Checkout
uses: actions/checkout@v2
- name: Setup | Rust
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.rust_toolchain }}
toolchain: ${{ matrix.rust_toolchain }}
components: rustfmt, clippy
- name: Setup | Std
run: rustup component add rust-src --toolchain ${{ env.rust_toolchain }}-x86_64-unknown-linux-gnu
run: rustup component add rust-src --toolchain ${{ matrix.rust_toolchain }}-x86_64-unknown-linux-gnu
- name: Setup | Set default toolchain
run: rustup default ${{ env.rust_toolchain }}
run: rustup default ${{ matrix.rust_toolchain }}
- name: Build | Fmt Check
run: cargo fmt -- --check
- name: Build | Clippy
Expand Down
14 changes: 7 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[package]
name = "async-io-mini"
version = "0.2.0"
version = "0.3.0"
authors = ["Stjepan Glavina <stjepang@gmail.com>", "Ivan Markov"]
edition = "2021"
rust-version = "1.77"
rust-version = "1.83"
description = "Async I/O fork for embedded systems"
license = "Apache-2.0 OR MIT"
repository = "https://github.com/ivmarkov/async-io-mini"
Expand All @@ -13,7 +13,7 @@ exclude = ["/.*"]

[features]
default = ["futures-io", "futures-lite", "embassy-time"]
embassy-time = ["embassy-time-driver", "embassy-time-queue-driver", "dep:embassy-time"]
embassy-time = ["embassy-time-driver", "dep:embassy-time"]

[dependencies]
libc = "0.2"
Expand All @@ -22,14 +22,14 @@ heapless = "0.8"
log = { version = "0.4", default-features = false }
futures-io = { version = "0.3", default-features = false, optional = true, features = ["std"] }
futures-lite = { version = "2", default-features = false, optional = true }
embassy-time-driver = { version = "0.1", optional = true }
embassy-time-queue-driver = { version = "0.1", optional = true }
embassy-time = { version = "0.3", optional = true }
embassy-time-driver = { version = "0.2", optional = true }
embassy-time = { version = "0.4", optional = true }

[dev-dependencies]
futures-io = "0.3"
futures-lite = "2"
embassy-time = { version = "0.3", features = ["std", "generic-queue"] }
embassy-time = { version = "0.4", features = ["std"] }
embassy-time-queue-utils = { version = "0.1", features = ["generic-queue-64"] }
async-channel = "2"
env_logger = "0.10"

Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ This crate is a fork of the splendid [`async-io`](https://github.com/smol-rs/asy

## How to use?

`async-io-mini` is a drop-in, API-compatible replacement for the `Async` and `Timer` types from `async-io`.
`async-io-mini` is an API-compatible replacement for the `Async` and `Timer` types from `async-io`.

So either:
* Just replace all `use async_io` occurances in your crate with `use async_io_mini`
* Or - in your `Cargo.toml` - replace:
* `async-io = "..."`
* with `async-io = { package = "async-io-mini", ... }`

Additionally, you need to provide an `embassy-time-driver` implementation. This is either done by the HAL of your MCU, or `embassy-time` provides you with a `std`-specific implementation. If you are not using `embassy-executor`, you will also need to select one of the `embassy-time/generic-queue-*` features.

## Justification

While `async-io` supports a ton of operating systems - _including ESP-IDF for the Espressif MCU chips_ - it does have a non-trivial memory consumption in the hidden thread named `async-io`. Since its hidden `Reactor` object is initialized lazily, it so happens that it is first allocated on-stack, and then it is moved into the static context. This requires the `async-io` thread (as well as _any_ thread from where you are polling sockets) to have at least 8K stack, which - by MCU standards! - is relatively large if you are memory-constrained.
Expand All @@ -39,7 +41,7 @@ Further, `async-io` has a non-trivial set of dependencies (again - for MCUs; for

## Enhancements

The `Timer` type of `async_io_mini` is based on the `embassy-time` crate, and as such should offer a higher resolution on embedded operating systems like the ESP-IDF than what can be normally achieved by implementing timers using the `timeout` parameter of the `select` syscall (as `async-io` does).
The `Timer` type of `async_io_mini` is based on the `embassy-time` crate, and as such should offer a higher resolution on embedded operating systems like the ESP-IDF than what can be normally achieved by implementing timers using the `timeout` parameter of the `select` syscall (as `async-io` does).

The reason for this is that on the ESP-IDF, the `timeout` parameter of `select` provides a resolution of 10ms (one FreeRTOS sys-tick), while
`embassy-time` is implemented using the [ESP-IDF Timer service](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/esp_timer.html), which provides resolutions up to 1 microsecond.
Expand Down
6 changes: 3 additions & 3 deletions src/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ impl Timer {
self.period = Duration::MAX;

if let Some(waker) = self.waker.as_ref() {
embassy_time_queue_driver::schedule_wake(ticks, waker);
embassy_time_driver::schedule_wake(ticks, waker);
}
} else {
self.set_never();
Expand Down Expand Up @@ -347,7 +347,7 @@ impl Timer {
self.period = period;

if let Some(waker) = self.waker.as_ref() {
embassy_time_queue_driver::schedule_wake(ticks, waker);
embassy_time_driver::schedule_wake(ticks, waker);
}
} else {
// Overflow to never going off.
Expand Down Expand Up @@ -375,7 +375,7 @@ impl Timer {
.unwrap_or(true)
{
self.waker = Some(cx.waker().clone());
embassy_time_queue_driver::schedule_wake(ticks, cx.waker());
embassy_time_driver::schedule_wake(ticks, cx.waker());
}
} else {
self.set_never();
Expand Down
Loading