about summary refs log tree commit diff
path: root/library/std/src/sys
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-02-10 12:10:02 +0100
committerGitHub <noreply@github.com>2022-02-10 12:10:02 +0100
commit8c60f4487733fb8fdbe2cfc2bbdb9dab736423f0 (patch)
tree12a64fb2b34aac646f821cedbb38195b84c9cf50 /library/std/src/sys
parent4256165411393e9f16ac60cbaa1b5e9f3876cbd0 (diff)
parent1d180caf1a14b3316652fa856499e44abec393b2 (diff)
downloadrust-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.rs13
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()?;