Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kmc-solid: Fix wait queue manipulation errors in the Condvar implementation #93843

Merged
merged 2 commits into from
Feb 10, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions library/std/src/sys/itron/condvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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`.
Expand All @@ -206,14 +208,16 @@ 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);

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
Expand All @@ -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;
Expand All @@ -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()?;
Expand Down