diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-02-10 12:10:02 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-02-10 12:10:02 +0100 |
| commit | 8c60f4487733fb8fdbe2cfc2bbdb9dab736423f0 (patch) | |
| tree | 12a64fb2b34aac646f821cedbb38195b84c9cf50 /library/std/src/sys | |
| parent | 4256165411393e9f16ac60cbaa1b5e9f3876cbd0 (diff) | |
| parent | 1d180caf1a14b3316652fa856499e44abec393b2 (diff) | |
| download | rust-8c60f4487733fb8fdbe2cfc2bbdb9dab736423f0.tar.gz rust-8c60f4487733fb8fdbe2cfc2bbdb9dab736423f0.zip | |
Rollup merge of #93843 - solid-rs:fix-kmc-solid-condvar, r=m-ou-se
kmc-solid: Fix wait queue manipulation errors in the `Condvar` implementation This PR fixes a number of bugs in the `Condvar` wait queue implementation used by the [`*-kmc-solid_*`](https://doc.rust-lang.org/nightly/rustc/platform-support/kmc-solid.html) Tier 3 targets. These bugs can occur when there are multiple threads waiting on the same `Condvar` and sometimes manifest as an `unwrap` failure.
Diffstat (limited to 'library/std/src/sys')
| -rw-r--r-- | library/std/src/sys/itron/condvar.rs | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/library/std/src/sys/itron/condvar.rs b/library/std/src/sys/itron/condvar.rs index dac4b8abfc4..2992a6a5429 100644 --- a/library/std/src/sys/itron/condvar.rs +++ b/library/std/src/sys/itron/condvar.rs @@ -15,10 +15,12 @@ unsafe impl Sync for Condvar {} pub type MovableCondvar = Condvar; impl Condvar { + #[inline] pub const fn new() -> Condvar { Condvar { waiters: SpinMutex::new(waiter_queue::WaiterQueue::new()) } } + #[inline] pub unsafe fn init(&mut self) {} pub unsafe fn notify_one(&self) { @@ -190,7 +192,7 @@ mod waiter_queue { let insert_after = { let mut cursor = head.last; loop { - if waiter.priority <= cursor.as_ref().priority { + if waiter.priority >= cursor.as_ref().priority { // `cursor` and all previous waiters have the same or higher // priority than `current_task_priority`. Insert the new // waiter right after `cursor`. @@ -206,7 +208,7 @@ mod waiter_queue { if let Some(mut insert_after) = insert_after { // Insert `waiter` after `insert_after` - let insert_before = insert_after.as_ref().prev; + let insert_before = insert_after.as_ref().next; waiter.prev = Some(insert_after); insert_after.as_mut().next = Some(waiter_ptr); @@ -214,6 +216,8 @@ mod waiter_queue { waiter.next = insert_before; if let Some(mut insert_before) = insert_before { insert_before.as_mut().prev = Some(waiter_ptr); + } else { + head.last = waiter_ptr; } } else { // Insert `waiter` to the front @@ -240,11 +244,11 @@ mod waiter_queue { match (waiter.prev, waiter.next) { (Some(mut prev), Some(mut next)) => { prev.as_mut().next = Some(next); - next.as_mut().next = Some(prev); + next.as_mut().prev = Some(prev); } (None, Some(mut next)) => { head.first = next; - next.as_mut().next = None; + next.as_mut().prev = None; } (Some(mut prev), None) => { prev.as_mut().next = None; @@ -271,6 +275,7 @@ mod waiter_queue { unsafe { waiter.as_ref().task != 0 } } + #[inline] pub fn pop_front(&mut self) -> Option<abi::ID> { unsafe { let head = self.head.as_mut()?; |
