Compare commits
8 Commits
Author | SHA1 | Date |
---|---|---|
John Nunley | 9969a29ccd | |
Taiki Endo | eba124f52a | |
John Nunley | 58880f9496 | |
John Nunley | 5de748aa9d | |
John Nunley | a46e243052 | |
Taiki Endo | dc095d0680 | |
Taiki Endo | 7e75b7ebe3 | |
daxpedda | 4320c6739e |
|
@ -1,5 +1,8 @@
|
|||
name: CI
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
|
@ -10,6 +13,7 @@ on:
|
|||
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
CARGO_NET_GIT_FETCH_WITH_CLI: true
|
||||
CARGO_NET_RETRY: 10
|
||||
CARGO_TERM_COLOR: always
|
||||
RUST_BACKTRACE: 1
|
||||
|
@ -30,7 +34,7 @@ jobs:
|
|||
os: [ubuntu-latest]
|
||||
rust: [nightly, beta, stable]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Rust
|
||||
run: rustup update ${{ matrix.rust }} && rustup default ${{ matrix.rust }}
|
||||
- run: rustup target add thumbv7m-none-eabi
|
||||
|
@ -49,7 +53,7 @@ jobs:
|
|||
# Rust version in Cargo.toml.
|
||||
rust: ['1.36']
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Rust
|
||||
run: rustup update ${{ matrix.rust }} && rustup default ${{ matrix.rust }}
|
||||
- run: cargo build
|
||||
|
@ -57,7 +61,7 @@ jobs:
|
|||
clippy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Rust
|
||||
run: rustup update stable
|
||||
- run: cargo clippy --all-features --all-targets
|
||||
|
@ -65,7 +69,7 @@ jobs:
|
|||
fmt:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Rust
|
||||
run: rustup update stable
|
||||
- run: cargo fmt --all --check
|
||||
|
@ -73,7 +77,7 @@ jobs:
|
|||
miri:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Rust
|
||||
run: rustup toolchain install nightly --component miri && rustup default nightly
|
||||
- run: cargo miri test
|
||||
|
@ -82,9 +86,13 @@ jobs:
|
|||
RUSTFLAGS: ${{ env.RUSTFLAGS }} -Z randomize-layout
|
||||
|
||||
security_audit:
|
||||
permissions:
|
||||
checks: write
|
||||
contents: read
|
||||
issues: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
# https://github.com/rustsec/audit-check/issues/2
|
||||
- uses: rustsec/audit-check@master
|
||||
with:
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
name: Release
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
|
@ -10,7 +13,7 @@ jobs:
|
|||
if: github.repository_owner == 'smol-rs'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: taiki-e/create-gh-release-action@v1
|
||||
with:
|
||||
changelog: CHANGELOG.md
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
# Version 1.1.2
|
||||
|
||||
- Add `smol-rs` logo to docs. (#16)
|
||||
|
||||
# Version 1.1.1
|
||||
|
||||
- Use `will_wake()` to avoid unnecessary cloning. (#12)
|
||||
|
||||
# Version 1.1.0
|
||||
|
||||
- Support `no_std` platforms. (#7)
|
||||
|
|
|
@ -3,7 +3,7 @@ name = "atomic-waker"
|
|||
# When publishing a new version:
|
||||
# - Update CHANGELOG.md
|
||||
# - Create "v1.x.y" git tag
|
||||
version = "1.1.0"
|
||||
version = "1.1.2"
|
||||
authors = [
|
||||
"Stjepan Glavina <stjepang@gmail.com>",
|
||||
"Contributors to futures-rs",
|
||||
|
@ -22,4 +22,10 @@ exclude = ["/.*"]
|
|||
portable-atomic = { version = "1", optional = true, default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = { version = "0.4.0", default-features = false, features = ["cargo_bench_support"] }
|
||||
futures = "0.3.5"
|
||||
rayon = "1.7.0"
|
||||
|
||||
[[bench]]
|
||||
name = "waker"
|
||||
harness = false
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
use atomic_waker::AtomicWaker;
|
||||
use criterion::{black_box, criterion_group, criterion_main, BenchmarkGroup, Criterion};
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::task::{Wake, Waker};
|
||||
|
||||
enum Contention {
|
||||
Low,
|
||||
High,
|
||||
}
|
||||
|
||||
impl Contention {
|
||||
fn bench<M>(
|
||||
self,
|
||||
group: &mut BenchmarkGroup<'_, M>,
|
||||
f: impl Fn(&AtomicWaker) + Send + Sync + Clone,
|
||||
) where
|
||||
M: criterion::measurement::Measurement,
|
||||
{
|
||||
let waker = AtomicWaker::new();
|
||||
|
||||
match self {
|
||||
Self::Low => {
|
||||
// Run the benchmark with low contention.
|
||||
group.bench_function("low contention", move |b| {
|
||||
b.iter(|| {
|
||||
for _ in 0..500 {
|
||||
f(&waker);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
Self::High => {
|
||||
// Run the benchmark with high contention.
|
||||
group.bench_function("high contention", move |b| {
|
||||
b.iter(|| {
|
||||
use rayon::prelude::*;
|
||||
(0..100_000).into_par_iter().for_each(|_| f(&waker));
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn run_lo_hi(c: &mut Criterion, name: &str, f: impl Fn(&AtomicWaker) + Send + Sync + Clone) {
|
||||
let mut group = c.benchmark_group(name);
|
||||
|
||||
Contention::Low.bench(&mut group, f.clone());
|
||||
Contention::High.bench(&mut group, f);
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
fn store_and_wake(c: &mut Criterion) {
|
||||
run_lo_hi(c, "store and wake", |waker| {
|
||||
let noop_waker = noop_waker();
|
||||
waker.register(&noop_waker);
|
||||
waker.wake();
|
||||
});
|
||||
|
||||
run_lo_hi(c, "store and take", |waker| {
|
||||
let noop_waker = noop_waker();
|
||||
waker.register(&noop_waker);
|
||||
black_box(waker.take());
|
||||
});
|
||||
}
|
||||
|
||||
fn wake_without_store(c: &mut Criterion) {
|
||||
run_lo_hi(c, "wake without store", |waker| {
|
||||
waker.wake();
|
||||
});
|
||||
|
||||
run_lo_hi(c, "take without store", |waker| {
|
||||
black_box(waker.take());
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(benches, store_and_wake, wake_without_store);
|
||||
|
||||
criterion_main!(benches);
|
||||
|
||||
fn noop_waker() -> Waker {
|
||||
struct Noop;
|
||||
|
||||
impl Wake for Noop {
|
||||
fn wake(self: Arc<Self>) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
fn wake_by_ref(self: &Arc<Self>) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
Waker::from(Arc::new(Noop))
|
||||
}
|
13
src/lib.rs
13
src/lib.rs
|
@ -11,6 +11,12 @@
|
|||
//! [`README`]: https://github.com/taiki-e/portable-atomic/blob/main/README.md#optional-cfg
|
||||
|
||||
#![no_std]
|
||||
#![doc(
|
||||
html_favicon_url = "https://raw.githubusercontent.com/smol-rs/smol/master/assets/images/logo_fullsize_transparent.png"
|
||||
)]
|
||||
#![doc(
|
||||
html_logo_url = "https://raw.githubusercontent.com/smol-rs/smol/master/assets/images/logo_fullsize_transparent.png"
|
||||
)]
|
||||
|
||||
use core::cell::UnsafeCell;
|
||||
use core::fmt;
|
||||
|
@ -285,7 +291,12 @@ impl AtomicWaker {
|
|||
WAITING => {
|
||||
unsafe {
|
||||
// Locked acquired, update the waker cell
|
||||
*self.waker.get() = Some(waker.clone());
|
||||
|
||||
// Avoid cloning the waker if the old waker will awaken the same task.
|
||||
match &*self.waker.get() {
|
||||
Some(old_waker) if old_waker.will_wake(waker) => (),
|
||||
_ => *self.waker.get() = Some(waker.clone()),
|
||||
}
|
||||
|
||||
// Release the lock. If the state transitioned to include
|
||||
// the `WAKING` bit, this means that at least one wake has
|
||||
|
|
Loading…
Reference in New Issue