Skip to content
Merged
Show file tree
Hide file tree
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
10 changes: 3 additions & 7 deletions api/src/imp/futex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub fn sys_futex(
if unsafe { uaddr.get()?.read() } != value {
return Err(LinuxError::EAGAIN);
}
let wq = futex_table.lock().get_or_insert(addr);
let wq = futex_table.get_or_insert(addr);

if let Some(timeout) = timeout.nullable(UserConstPtr::get)? {
wq.wait_timeout(unsafe { *timeout }.into());
Expand All @@ -38,7 +38,7 @@ pub fn sys_futex(
Ok(0)
}
FUTEX_WAKE => {
let wq = futex_table.lock().get(addr);
let wq = futex_table.get(addr);
let mut count = 0;
if let Some(wq) = wq {
for _ in 0..value {
Expand All @@ -57,12 +57,8 @@ pub fn sys_futex(
}
let value2 = timeout.address().as_usize() as u32;

let mut futex_table = futex_table.lock();
let wq = futex_table.get(addr);
let wq2 = futex_table
.get_or_insert(uaddr2.address().as_usize())
.clone();
drop(futex_table);
let wq2 = futex_table.get_or_insert(uaddr2.address().as_usize());

let mut count = 0;
if let Some(wq) = wq {
Expand Down
4 changes: 0 additions & 4 deletions api/src/imp/task/exit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,9 @@ pub fn do_exit(exit_code: i32, group_exit: bool) -> ! {
if let Ok(clear_tid) = clear_child_tid.get() {
unsafe { clear_tid.write(0) };

// Since `guard` (WaitQueueGuard) acquires lock to the futex table on
// drop, we need to ensure that the temporary lock's lifetime is
// encapsulated within `guard`'s scope.
let guard = curr_ext
.process_data()
.futex_table
.lock()
.get(clear_tid as *const _ as usize);
if let Some(futex) = guard {
futex.notify_one(false);
Expand Down
21 changes: 13 additions & 8 deletions core/src/futex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,20 @@
use core::ops::Deref;

use alloc::{collections::btree_map::BTreeMap, sync::Arc};
use axsync::Mutex;
use axtask::{TaskExtRef, WaitQueue, current};

/// A table mapping memory addresses to futex wait queues.
#[derive(Default)]
pub struct FutexTable(BTreeMap<usize, Arc<WaitQueue>>);
pub struct FutexTable(Mutex<BTreeMap<usize, Arc<WaitQueue>>>);
impl FutexTable {
/// Creates a new `FutexTable`.
pub fn new() -> Self {
Self(Mutex::new(BTreeMap::new()))
}

/// Gets the wait queue associated with the given address.
pub fn get(&self, addr: usize) -> Option<WaitQueueGuard> {
let wq = self.0.get(&addr).cloned()?;
let wq = self.0.lock().get(&addr).cloned()?;
Some(WaitQueueGuard {
key: addr,
inner: wq,
Expand All @@ -20,9 +25,9 @@ impl FutexTable {

/// Gets the wait queue associated with the given address, or inserts a a
/// new one if it doesn't exist.
pub fn get_or_insert(&mut self, addr: usize) -> WaitQueueGuard {
let wq = self
.0
pub fn get_or_insert(&self, addr: usize) -> WaitQueueGuard {
let mut table = self.0.lock();
let wq = table
.entry(addr)
.or_insert_with(|| Arc::new(WaitQueue::new()));
WaitQueueGuard {
Expand All @@ -47,9 +52,9 @@ impl Deref for WaitQueueGuard {
impl Drop for WaitQueueGuard {
fn drop(&mut self) {
let curr = current();
let mut table = curr.task_ext().process_data().futex_table.lock();
let mut table = curr.task_ext().process_data().futex_table.0.lock();
if Arc::strong_count(&self.inner) == 1 && self.inner.is_empty() {
table.0.remove(&self.key);
table.remove(&self.key);
}
}
}
4 changes: 2 additions & 2 deletions core/src/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ pub struct ProcessData {
pub signal: Arc<ProcessSignalManager<RawMutex, WaitQueueWrapper>>,

/// The futex table.
pub futex_table: Mutex<FutexTable>,
pub futex_table: FutexTable,
}

impl ProcessData {
Expand All @@ -235,7 +235,7 @@ impl ProcessData {
axconfig::plat::SIGNAL_TRAMPOLINE,
)),

futex_table: Mutex::default(),
futex_table: FutexTable::new(),
}
}

Expand Down
Loading