mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-27 14:04:56 +01:00
Fix if a enqueued instant is first in a non-empty queue
This commit is contained in:
parent
d9f2980c38
commit
66780d8a7b
6 changed files with 20 additions and 17 deletions
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "rtic-monotonics"
|
name = "rtic-monotonics"
|
||||||
version = "1.0.0-alpha.0"
|
version = "1.0.0-alpha.1"
|
||||||
|
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = [
|
authors = [
|
||||||
|
@ -17,7 +17,7 @@ license = "MIT OR Apache-2.0"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rtic-time = { version = "1.0.0-alpha.0", path = "../rtic-time" }
|
rtic-time = { version = "1.0.0-alpha.1", path = "../rtic-time" }
|
||||||
embedded-hal-async = { version = "0.2.0-alpha.0", optional = true }
|
embedded-hal-async = { version = "0.2.0-alpha.0", optional = true }
|
||||||
fugit = { version = "0.3.6" }
|
fugit = { version = "0.3.6" }
|
||||||
atomic-polyfill = "1"
|
atomic-polyfill = "1"
|
||||||
|
|
|
@ -15,4 +15,6 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top!
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
- If the queue was non-empty and a new instant was added that was earlier than `head`, then the queue would no pend the monotonic handler. This would cause the new `head` to be dequeued at the wrong time.
|
||||||
|
|
||||||
## [v1.0.0] - 2023-xx-xx
|
## [v1.0.0] - 2023-xx-xx
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "rtic-time"
|
name = "rtic-time"
|
||||||
version = "1.0.0-alpha.0"
|
version = "1.0.0-alpha.1"
|
||||||
|
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = [
|
authors = [
|
||||||
|
|
|
@ -25,7 +25,7 @@ mod monotonic;
|
||||||
struct WaitingWaker<Mono: Monotonic> {
|
struct WaitingWaker<Mono: Monotonic> {
|
||||||
waker: Waker,
|
waker: Waker,
|
||||||
release_at: Mono::Instant,
|
release_at: Mono::Instant,
|
||||||
was_poped: AtomicBool,
|
was_popped: AtomicBool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Mono: Monotonic> Clone for WaitingWaker<Mono> {
|
impl<Mono: Monotonic> Clone for WaitingWaker<Mono> {
|
||||||
|
@ -33,7 +33,7 @@ impl<Mono: Monotonic> Clone for WaitingWaker<Mono> {
|
||||||
Self {
|
Self {
|
||||||
waker: self.waker.clone(),
|
waker: self.waker.clone(),
|
||||||
release_at: self.release_at,
|
release_at: self.release_at,
|
||||||
was_poped: AtomicBool::new(self.was_poped.load(Ordering::Relaxed)),
|
was_popped: AtomicBool::new(self.was_popped.load(Ordering::Relaxed)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ impl<Mono: Monotonic> TimerQueue<Mono> {
|
||||||
release_at = Some(head.release_at);
|
release_at = Some(head.release_at);
|
||||||
|
|
||||||
let should_pop = Mono::should_dequeue_check(head.release_at);
|
let should_pop = Mono::should_dequeue_check(head.release_at);
|
||||||
head.was_poped.store(should_pop, Ordering::Relaxed);
|
head.was_popped.store(should_pop, Ordering::Relaxed);
|
||||||
|
|
||||||
should_pop
|
should_pop
|
||||||
});
|
});
|
||||||
|
@ -234,7 +234,7 @@ impl<Mono: Monotonic> TimerQueue<Mono> {
|
||||||
let link_ref = link.insert(Link::new(WaitingWaker {
|
let link_ref = link.insert(Link::new(WaitingWaker {
|
||||||
waker: cx.waker().clone(),
|
waker: cx.waker().clone(),
|
||||||
release_at: instant,
|
release_at: instant,
|
||||||
was_poped: AtomicBool::new(false),
|
was_popped: AtomicBool::new(false),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// SAFETY(new_unchecked): The address to the link is stable as it is defined
|
// SAFETY(new_unchecked): The address to the link is stable as it is defined
|
||||||
|
@ -243,13 +243,13 @@ impl<Mono: Monotonic> TimerQueue<Mono> {
|
||||||
// we make sure in `dropper` that the link is removed from the queue before
|
// we make sure in `dropper` that the link is removed from the queue before
|
||||||
// dropping `link_ptr` AND `dropper` makes sure that the shadowed `link_ptr` lives
|
// dropping `link_ptr` AND `dropper` makes sure that the shadowed `link_ptr` lives
|
||||||
// until the end of the stack frame.
|
// until the end of the stack frame.
|
||||||
let (was_empty, addr) = unsafe { queue.insert(Pin::new_unchecked(link_ref)) };
|
let (head_updated, addr) = unsafe { queue.insert(Pin::new_unchecked(link_ref)) };
|
||||||
|
|
||||||
marker.store(addr, Ordering::Relaxed);
|
marker.store(addr, Ordering::Relaxed);
|
||||||
|
|
||||||
if was_empty {
|
if head_updated {
|
||||||
// Pend the monotonic handler if the queue was empty to setup the timer.
|
// Pend the monotonic handler if the queue head was updated.
|
||||||
Mono::pend_interrupt();
|
Mono::pend_interrupt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,8 +261,8 @@ impl<Mono: Monotonic> TimerQueue<Mono> {
|
||||||
// exited the `poll_fn` below in the `drop(dropper)` call. The other dereference
|
// exited the `poll_fn` below in the `drop(dropper)` call. The other dereference
|
||||||
// of this pointer is in the `poll_fn`.
|
// of this pointer is in the `poll_fn`.
|
||||||
if let Some(link) = unsafe { link_ptr.get() } {
|
if let Some(link) = unsafe { link_ptr.get() } {
|
||||||
if link.val.was_poped.load(Ordering::Relaxed) {
|
if link.val.was_popped.load(Ordering::Relaxed) {
|
||||||
// If it was poped from the queue there is no need to run delete
|
// If it was popped from the queue there is no need to run delete
|
||||||
dropper.defuse();
|
dropper.defuse();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -92,7 +92,8 @@ impl<T: PartialOrd + Clone> LinkedList<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert a new link into the linked list.
|
/// Insert a new link into the linked list.
|
||||||
/// The return is (was_empty, address), where the address of the link is for use with `delete`.
|
/// The return is (updated head, address), where the address of the link is for use
|
||||||
|
/// with `delete`.
|
||||||
///
|
///
|
||||||
/// SAFETY: The pinned link must live until it is removed from this list.
|
/// SAFETY: The pinned link must live until it is removed from this list.
|
||||||
pub unsafe fn insert(&self, val: Pin<&Link<T>>) -> (bool, usize) {
|
pub unsafe fn insert(&self, val: Pin<&Link<T>>) -> (bool, usize) {
|
||||||
|
@ -127,7 +128,7 @@ impl<T: PartialOrd + Clone> LinkedList<T> {
|
||||||
self.head
|
self.head
|
||||||
.store(val as *const _ as *mut _, Ordering::Relaxed);
|
.store(val as *const _ as *mut _, Ordering::Relaxed);
|
||||||
|
|
||||||
return (false, addr);
|
return (true, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. search list for correct place
|
// 3. search list for correct place
|
||||||
|
|
|
@ -22,7 +22,7 @@ name = "rtic"
|
||||||
readme = "../README.md"
|
readme = "../README.md"
|
||||||
repository = "https://github.com/rtic-rs/rtic"
|
repository = "https://github.com/rtic-rs/rtic"
|
||||||
|
|
||||||
version = "2.0.0-alpha.0"
|
version = "2.0.0-alpha.1"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "rtic"
|
name = "rtic"
|
||||||
|
@ -32,7 +32,7 @@ cortex-m = { version = "0.7.0", optional = true }
|
||||||
bare-metal = "1.0.0"
|
bare-metal = "1.0.0"
|
||||||
#portable-atomic = { version = "0.3.19" }
|
#portable-atomic = { version = "0.3.19" }
|
||||||
atomic-polyfill = "1"
|
atomic-polyfill = "1"
|
||||||
rtic-monotonics = { path = "../rtic-monotonics", version = "1.0.0-alpha.0", optional = true }
|
rtic-monotonics = { path = "../rtic-monotonics", version = "1.0.0-alpha.1", optional = true }
|
||||||
rtic-macros = { path = "../rtic-macros", version = "2.0.0-alpha.0" }
|
rtic-macros = { path = "../rtic-macros", version = "2.0.0-alpha.0" }
|
||||||
rtic-core = "1"
|
rtic-core = "1"
|
||||||
critical-section = "1"
|
critical-section = "1"
|
||||||
|
|
Loading…
Reference in a new issue