1
Fork 0

Move thread parking to a seperate function

This commit is contained in:
Paul Dicker 2019-10-23 10:01:22 +02:00
parent fbc242f1ef
commit 2e8eb5f33d

View file

@ -401,6 +401,15 @@ impl Once {
// not RUNNING. // not RUNNING.
_ => { _ => {
assert!(state_and_queue & STATE_MASK == RUNNING); assert!(state_and_queue & STATE_MASK == RUNNING);
wait(&self.state_and_queue, state_and_queue);
state_and_queue = self.state_and_queue.load(Ordering::SeqCst);
}
}
}
}
}
fn wait(state_and_queue: &AtomicUsize, current_state: usize) {
// Create the node for our current thread that we are going to try to slot // Create the node for our current thread that we are going to try to slot
// in at the head of the linked list. // in at the head of the linked list.
let mut node = Waiter { let mut node = Waiter {
@ -415,14 +424,14 @@ impl Once {
// Try to slide in the node at the head of the linked list. // Try to slide in the node at the head of the linked list.
// Run in a loop where we make sure the status is still RUNNING, and that // Run in a loop where we make sure the status is still RUNNING, and that
// another thread did not just replace the head of the linked list. // another thread did not just replace the head of the linked list.
let mut old_head_and_status = state_and_queue; let mut old_head_and_status = current_state;
loop { loop {
if old_head_and_status & STATE_MASK != RUNNING { if old_head_and_status & STATE_MASK != RUNNING {
return; // No need anymore to enqueue ourselves. return; // No need anymore to enqueue ourselves.
} }
node.next = (old_head_and_status & !STATE_MASK) as *const Waiter; node.next = (old_head_and_status & !STATE_MASK) as *const Waiter;
let old = self.state_and_queue.compare_and_swap(old_head_and_status, let old = state_and_queue.compare_and_swap(old_head_and_status,
me | RUNNING, me | RUNNING,
Ordering::Release); Ordering::Release);
if old == old_head_and_status { if old == old_head_and_status {
@ -439,11 +448,6 @@ impl Once {
while !node.signaled.load(Ordering::SeqCst) { while !node.signaled.load(Ordering::SeqCst) {
thread::park(); thread::park();
} }
state_and_queue = self.state_and_queue.load(Ordering::SeqCst);
}
}
}
}
} }
#[stable(feature = "std_debug", since = "1.16.0")] #[stable(feature = "std_debug", since = "1.16.0")]