mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 09:53:24 +00:00
Use WaitQueue to implement waiting in FutexWaiter
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
34f6108f56
commit
31746e2ebf
@ -4,14 +4,10 @@
|
|||||||
|
|
||||||
use core::sync::atomic::{AtomicBool, Ordering};
|
use core::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
use ostd::cpu::num_cpus;
|
use ostd::{cpu::num_cpus, sync::WaitQueue};
|
||||||
use spin::Once;
|
use spin::Once;
|
||||||
|
|
||||||
use crate::{
|
use crate::{prelude::*, thread::Tid, util::read_val_from_user};
|
||||||
prelude::*,
|
|
||||||
thread::{Thread, Tid},
|
|
||||||
util::read_val_from_user,
|
|
||||||
};
|
|
||||||
|
|
||||||
type FutexBitSet = u32;
|
type FutexBitSet = u32;
|
||||||
type FutexBucketRef = Arc<Mutex<FutexBucket>>;
|
type FutexBucketRef = Arc<Mutex<FutexBucket>>;
|
||||||
@ -51,7 +47,7 @@ pub fn futex_wait_bitset(
|
|||||||
// drop lock
|
// drop lock
|
||||||
drop(futex_bucket);
|
drop(futex_bucket);
|
||||||
// Wait on the futex item
|
// Wait on the futex item
|
||||||
futex_item.wait();
|
futex_item.wait(timeout.clone());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -302,9 +298,9 @@ impl FutexItem {
|
|||||||
self.waiter.wake();
|
self.waiter.wake();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wait(&self) {
|
pub fn wait(&self, timeout: Option<FutexTimeout>) {
|
||||||
// debug!("wait on futex item, key = {:?}", self.key);
|
// debug!("wait on futex item, key = {:?}", self.key);
|
||||||
self.waiter.wait();
|
self.waiter.wait(timeout);
|
||||||
// debug!("wait finished, key = {:?}", self.key);
|
// debug!("wait finished, key = {:?}", self.key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,12 +399,21 @@ pub fn futex_op_and_flags_from_u32(bits: u32) -> Result<(FutexOp, FutexFlags)> {
|
|||||||
|
|
||||||
type FutexWaiterRef = Arc<FutexWaiter>;
|
type FutexWaiterRef = Arc<FutexWaiter>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct FutexWaiter {
|
struct FutexWaiter {
|
||||||
is_woken: AtomicBool,
|
is_woken: AtomicBool,
|
||||||
|
wait_queue: WaitQueue,
|
||||||
tid: Tid,
|
tid: Tid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for FutexWaiter {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
f.debug_struct("FutexWaiter")
|
||||||
|
.field("is_woken", &self.is_woken)
|
||||||
|
.field("tid", &self.tid)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq for FutexWaiter {
|
impl PartialEq for FutexWaiter {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.tid == other.tid
|
self.tid == other.tid
|
||||||
@ -420,26 +425,37 @@ impl FutexWaiter {
|
|||||||
Self {
|
Self {
|
||||||
is_woken: AtomicBool::new(false),
|
is_woken: AtomicBool::new(false),
|
||||||
tid: current_thread!().tid(),
|
tid: current_thread!().tid(),
|
||||||
|
wait_queue: WaitQueue::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wait(&self) {
|
pub fn wait(&self, timeout: Option<FutexTimeout>) {
|
||||||
let current_thread = current_thread!();
|
let current_thread = current_thread!();
|
||||||
if current_thread.tid() != self.tid {
|
if current_thread.tid() != self.tid {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.is_woken.store(false, Ordering::SeqCst);
|
self.is_woken.store(false, Ordering::SeqCst);
|
||||||
while !self.is_woken() {
|
let wake_cond = || {
|
||||||
// debug!("futex is wait for waken, tid = {}", self.tid);
|
if self.is_woken() {
|
||||||
Thread::yield_now();
|
Some(())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(_timeout) = timeout {
|
||||||
|
todo!()
|
||||||
|
} else {
|
||||||
|
self.wait_queue.wait_until(wake_cond);
|
||||||
}
|
}
|
||||||
// debug!("futex is waken, tid = {}", self.tid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wake(&self) {
|
pub fn wake(&self) {
|
||||||
if !self.is_woken() {
|
if !self.is_woken() {
|
||||||
// debug!("wake up futex, tid = {}", self.tid);
|
// debug!("wake up futex, tid = {}", self.tid);
|
||||||
self.is_woken.store(true, Ordering::SeqCst);
|
self.is_woken.store(true, Ordering::SeqCst);
|
||||||
|
self.wait_queue.wake_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user