Skip to content

Commit 8c60f44

Browse files
authored
Rollup merge of rust-lang#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.
2 parents 4256165 + 1d180ca commit 8c60f44

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

library/std/src/sys/itron/condvar.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ unsafe impl Sync for Condvar {}
1515
pub type MovableCondvar = Condvar;
1616

1717
impl Condvar {
18+
#[inline]
1819
pub const fn new() -> Condvar {
1920
Condvar { waiters: SpinMutex::new(waiter_queue::WaiterQueue::new()) }
2021
}
2122

23+
#[inline]
2224
pub unsafe fn init(&mut self) {}
2325

2426
pub unsafe fn notify_one(&self) {
@@ -190,7 +192,7 @@ mod waiter_queue {
190192
let insert_after = {
191193
let mut cursor = head.last;
192194
loop {
193-
if waiter.priority <= cursor.as_ref().priority {
195+
if waiter.priority >= cursor.as_ref().priority {
194196
// `cursor` and all previous waiters have the same or higher
195197
// priority than `current_task_priority`. Insert the new
196198
// waiter right after `cursor`.
@@ -206,14 +208,16 @@ mod waiter_queue {
206208

207209
if let Some(mut insert_after) = insert_after {
208210
// Insert `waiter` after `insert_after`
209-
let insert_before = insert_after.as_ref().prev;
211+
let insert_before = insert_after.as_ref().next;
210212

211213
waiter.prev = Some(insert_after);
212214
insert_after.as_mut().next = Some(waiter_ptr);
213215

214216
waiter.next = insert_before;
215217
if let Some(mut insert_before) = insert_before {
216218
insert_before.as_mut().prev = Some(waiter_ptr);
219+
} else {
220+
head.last = waiter_ptr;
217221
}
218222
} else {
219223
// Insert `waiter` to the front
@@ -240,11 +244,11 @@ mod waiter_queue {
240244
match (waiter.prev, waiter.next) {
241245
(Some(mut prev), Some(mut next)) => {
242246
prev.as_mut().next = Some(next);
243-
next.as_mut().next = Some(prev);
247+
next.as_mut().prev = Some(prev);
244248
}
245249
(None, Some(mut next)) => {
246250
head.first = next;
247-
next.as_mut().next = None;
251+
next.as_mut().prev = None;
248252
}
249253
(Some(mut prev), None) => {
250254
prev.as_mut().next = None;
@@ -271,6 +275,7 @@ mod waiter_queue {
271275
unsafe { waiter.as_ref().task != 0 }
272276
}
273277

278+
#[inline]
274279
pub fn pop_front(&mut self) -> Option<abi::ID> {
275280
unsafe {
276281
let head = self.head.as_mut()?;

0 commit comments

Comments
 (0)