forked from rcore-os/zCore
Fix pthread_cond & pthread_tsd & ...
This commit is contained in:
parent
d6687d9a65
commit
767e9dd745
|
@ -1,7 +1,7 @@
|
||||||
//! Linux kernel objects
|
//! Linux kernel objects
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
// #![deny(warnings, unsafe_code, missing_docs)]
|
#![deny(warnings, unsafe_code, missing_docs)]
|
||||||
#![allow(clippy::upper_case_acronyms)]
|
#![allow(clippy::upper_case_acronyms)]
|
||||||
#![allow(clippy::uninit_vec)]
|
#![allow(clippy::uninit_vec)]
|
||||||
#![feature(bool_to_option)]
|
#![feature(bool_to_option)]
|
||||||
|
|
|
@ -241,21 +241,16 @@ impl LinuxProcess {
|
||||||
|
|
||||||
/// Get futex object.
|
/// Get futex object.
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub fn get_futex(&self, uaddr: VirtAddr) -> Option<Arc<Futex>> {
|
pub fn get_futex(&self, uaddr: VirtAddr) -> Arc<Futex> {
|
||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
// if uaddr == 683520 {
|
inner
|
||||||
// return None;
|
.futexes
|
||||||
// }
|
.entry(uaddr)
|
||||||
Some(
|
.or_insert_with(|| {
|
||||||
inner
|
let value = unsafe { &*(uaddr as *const AtomicI32) };
|
||||||
.futexes
|
Futex::new(value)
|
||||||
.entry(uaddr)
|
})
|
||||||
.or_insert_with(|| {
|
.clone()
|
||||||
let value = unsafe { &*(uaddr as *const AtomicI32) };
|
|
||||||
Futex::new(value)
|
|
||||||
})
|
|
||||||
.clone(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get lowest free fd
|
/// Get lowest free fd
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
//! Linux Thread
|
//! Linux Thread
|
||||||
|
|
||||||
use crate::error::LxError;
|
|
||||||
use crate::error::SysResult;
|
use crate::error::SysResult;
|
||||||
use crate::process::ProcessExt;
|
use crate::process::ProcessExt;
|
||||||
use crate::signal::{SignalStack, Sigset};
|
use crate::signal::{SignalStack, Sigset};
|
||||||
|
@ -22,8 +21,8 @@ pub trait ThreadExt {
|
||||||
/// Get robust list.
|
/// Get robust list.
|
||||||
fn get_robust_list(
|
fn get_robust_list(
|
||||||
&self,
|
&self,
|
||||||
head_ptr: UserOutPtr<UserOutPtr<RobustList>>,
|
_head_ptr: UserOutPtr<UserOutPtr<RobustList>>,
|
||||||
len_ptr: UserOutPtr<usize>,
|
_len_ptr: UserOutPtr<usize>,
|
||||||
) -> SysResult;
|
) -> SysResult;
|
||||||
/// Set robust list.
|
/// Set robust list.
|
||||||
fn set_robust_list(&self, head: UserInPtr<RobustList>, len: usize);
|
fn set_robust_list(&self, head: UserInPtr<RobustList>, len: usize);
|
||||||
|
@ -61,14 +60,11 @@ impl ThreadExt for Thread {
|
||||||
|
|
||||||
fn get_robust_list(
|
fn get_robust_list(
|
||||||
&self,
|
&self,
|
||||||
mut head_ptr: UserOutPtr<UserOutPtr<RobustList>>,
|
mut _head_ptr: UserOutPtr<UserOutPtr<RobustList>>,
|
||||||
mut len_ptr: UserOutPtr<usize>,
|
mut _len_ptr: UserOutPtr<usize>,
|
||||||
) -> SysResult {
|
) -> SysResult {
|
||||||
// if self.lock_linux().robust_list_len == 0 {
|
_head_ptr = (self.lock_linux().robust_list.as_ptr() as *mut RobustList as usize).into();
|
||||||
// return Err(LxError::EFAULT);
|
_len_ptr = (&self.lock_linux().robust_list_len as *const usize as usize).into();
|
||||||
// }
|
|
||||||
head_ptr = (self.lock_linux().robust_list.as_ptr() as *mut RobustList as usize).into();
|
|
||||||
len_ptr = (&self.lock_linux().robust_list_len as *const usize as usize).into();
|
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +85,7 @@ impl CurrentThreadExt for CurrentThread {
|
||||||
info!("exit: do futex {:?} wake 1", clear_child_tid);
|
info!("exit: do futex {:?} wake 1", clear_child_tid);
|
||||||
clear_child_tid.write(0).unwrap();
|
clear_child_tid.write(0).unwrap();
|
||||||
let uaddr = clear_child_tid.as_ptr() as VirtAddr;
|
let uaddr = clear_child_tid.as_ptr() as VirtAddr;
|
||||||
let futex = self.proc().linux().get_futex(uaddr).unwrap();
|
let futex = self.proc().linux().get_futex(uaddr);
|
||||||
futex.wake(1);
|
futex.wake(1);
|
||||||
}
|
}
|
||||||
self.exit();
|
self.exit();
|
||||||
|
@ -100,11 +96,11 @@ impl CurrentThreadExt for CurrentThread {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct RobustList {
|
pub struct RobustList {
|
||||||
/// head
|
/// head
|
||||||
head: usize,
|
pub head: usize,
|
||||||
/// off
|
/// off
|
||||||
pub off: isize,
|
pub off: isize,
|
||||||
/// pending
|
/// pending
|
||||||
pending: usize,
|
pub pending: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Linux specific thread information.
|
/// Linux specific thread information.
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
//!
|
//!
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
// #![deny(warnings, unsafe_code, missing_docs)]
|
#![deny(warnings, unsafe_code, missing_docs)]
|
||||||
#![allow(clippy::upper_case_acronyms)]
|
#![allow(clippy::upper_case_acronyms)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -363,10 +363,6 @@ impl Syscall<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// process
|
// process
|
||||||
#[cfg(target_arch = "riscv64")]
|
|
||||||
Sys::CLONE => self.sys_clone(a0, a1, a2.into(), a3, a4.into()),
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
Sys::CLONE => self.sys_clone(a0, a1, a2.into(), a4, a3.into()),
|
|
||||||
Sys::EXECVE => self.sys_execve(
|
Sys::EXECVE => self.sys_execve(
|
||||||
self.into_in_userptr(a0).unwrap(),
|
self.into_in_userptr(a0).unwrap(),
|
||||||
self.into_in_userptr(a1).unwrap(),
|
self.into_in_userptr(a1).unwrap(),
|
||||||
|
@ -379,7 +375,10 @@ impl Syscall<'_> {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
Sys::SET_TID_ADDRESS => self.sys_set_tid_address(self.into_out_userptr(a0).unwrap()),
|
Sys::SET_TID_ADDRESS => self.sys_set_tid_address(self.into_out_userptr(a0).unwrap()),
|
||||||
Sys::FUTEX => self.sys_futex(a0, a1 as _, a2 as _, a3).await,
|
Sys::FUTEX => {
|
||||||
|
info!("Futex: {} {} {} {} {} {}", a0, a1, a2, a3, a4, a5);
|
||||||
|
self.sys_futex(a0, a1 as _, a2 as _, a3, a4, a5 as _).await
|
||||||
|
}
|
||||||
// Sys::FUTEX => self.unimplemented("futex", Ok(0)),
|
// Sys::FUTEX => self.unimplemented("futex", Ok(0)),
|
||||||
Sys::TKILL => self.unimplemented("tkill", Ok(0)),
|
Sys::TKILL => self.unimplemented("tkill", Ok(0)),
|
||||||
Sys::GET_ROBUST_LIST => {
|
Sys::GET_ROBUST_LIST => {
|
||||||
|
@ -532,6 +531,7 @@ impl Syscall<'_> {
|
||||||
Sys::CHOWN => self.unimplemented("chown", Ok(0)),
|
Sys::CHOWN => self.unimplemented("chown", Ok(0)),
|
||||||
Sys::ARCH_PRCTL => self.sys_arch_prctl(a0 as _, a1),
|
Sys::ARCH_PRCTL => self.sys_arch_prctl(a0 as _, a1),
|
||||||
Sys::TIME => self.sys_time(self.into_out_userptr(a0).unwrap()),
|
Sys::TIME => self.sys_time(self.into_out_userptr(a0).unwrap()),
|
||||||
|
Sys::CLONE => self.sys_clone(a0, a1, a2.into(), a4, a3.into()),
|
||||||
// Sys::EPOLL_CREATE => self.sys_epoll_create(a0),
|
// Sys::EPOLL_CREATE => self.sys_epoll_create(a0),
|
||||||
// Sys::EPOLL_WAIT => self.sys_epoll_wait(a0, a1.into(), a2, a3),
|
// Sys::EPOLL_WAIT => self.sys_epoll_wait(a0, a1.into(), a2, a3),
|
||||||
_ => self.unknown_syscall(sys_type),
|
_ => self.unknown_syscall(sys_type),
|
||||||
|
@ -540,10 +540,10 @@ impl Syscall<'_> {
|
||||||
|
|
||||||
#[cfg(target_arch = "riscv64")]
|
#[cfg(target_arch = "riscv64")]
|
||||||
async fn riscv64_syscall(&mut self, sys_type: Sys, args: [usize; 6]) -> SysResult {
|
async fn riscv64_syscall(&mut self, sys_type: Sys, args: [usize; 6]) -> SysResult {
|
||||||
debug!("riscv64_syscall: {:?}, {:?}", sys_type, args);
|
let [a0, a1, a2, a3, a4, _a5] = args;
|
||||||
//let [a0, a1, a2, a3, a4, _a5] = args;
|
|
||||||
match sys_type {
|
match sys_type {
|
||||||
//Sys::OPEN => self.sys_open(a0.into(), a1, a2),
|
//Sys::OPEN => self.sys_open(a0.into(), a1, a2),
|
||||||
|
Sys::CLONE => self.sys_clone(a0, a1, a2.into(), a3, a4.into()),
|
||||||
_ => self.unknown_syscall(sys_type),
|
_ => self.unknown_syscall(sys_type),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,7 @@ use core::time::Duration;
|
||||||
use futures::pin_mut;
|
use futures::pin_mut;
|
||||||
use kernel_hal::timer::timer_now;
|
use kernel_hal::timer::timer_now;
|
||||||
use linux_object::time::*;
|
use linux_object::time::*;
|
||||||
use zircon_object::{
|
use zircon_object::task::ThreadState;
|
||||||
task::{IntoResult, ThreadState},
|
|
||||||
ZxResult,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl Syscall<'_> {
|
impl Syscall<'_> {
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
@ -82,6 +79,8 @@ impl Syscall<'_> {
|
||||||
op: u32,
|
op: u32,
|
||||||
val: u32,
|
val: u32,
|
||||||
timeout_addr: usize,
|
timeout_addr: usize,
|
||||||
|
uaddr2: usize,
|
||||||
|
_val3: u32,
|
||||||
) -> SysResult {
|
) -> SysResult {
|
||||||
if let Err(_) = self.into_inout_userptr::<i32>(uaddr) {
|
if let Err(_) = self.into_inout_userptr::<i32>(uaddr) {
|
||||||
return Err(LxError::EINVAL);
|
return Err(LxError::EINVAL);
|
||||||
|
@ -89,9 +88,15 @@ impl Syscall<'_> {
|
||||||
let op = FutexFlags::from_bits_truncate(op);
|
let op = FutexFlags::from_bits_truncate(op);
|
||||||
if !op.contains(FutexFlags::PRIVATE) {
|
if !op.contains(FutexFlags::PRIVATE) {
|
||||||
warn!("process-shared futex is unimplemented");
|
warn!("process-shared futex is unimplemented");
|
||||||
return Err(LxError::ENOPROTOOPT);
|
// return Err(LxError::ENOPROTOOPT);
|
||||||
|
}
|
||||||
|
let mut val2 = 0;
|
||||||
|
if op.contains(FutexFlags::REQUEUE) {
|
||||||
|
if let Err(_) = self.into_inout_userptr::<i32>(uaddr2) {
|
||||||
|
return Err(LxError::EINVAL);
|
||||||
|
}
|
||||||
|
val2 = timeout_addr;
|
||||||
}
|
}
|
||||||
let op = op - FutexFlags::PRIVATE;
|
|
||||||
let timeout = if op.contains(FutexFlags::WAKE) {
|
let timeout = if op.contains(FutexFlags::WAKE) {
|
||||||
self.into_inout_userptr::<TimeSpec>(0).unwrap()
|
self.into_inout_userptr::<TimeSpec>(0).unwrap()
|
||||||
} else {
|
} else {
|
||||||
|
@ -102,55 +107,96 @@ impl Syscall<'_> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
warn!(
|
warn!(
|
||||||
"Futex: uaddr: {:#x}, op: {:x}, val: {}, timeout_ptr: {:x?}",
|
"Futex: uaddr: {:#x}, op: {:x}, val: {}, timeout_ptr: {:x?}, val2: {}",
|
||||||
uaddr,
|
uaddr,
|
||||||
op.bits(),
|
op.bits(),
|
||||||
val,
|
val,
|
||||||
timeout
|
timeout,
|
||||||
|
val2,
|
||||||
);
|
);
|
||||||
let futex_op = self.linux_process().get_futex(uaddr);
|
let futex = self.linux_process().get_futex(uaddr);
|
||||||
match futex_op {
|
let op = op - FutexFlags::PRIVATE;
|
||||||
Some(futex) => match op {
|
match op {
|
||||||
FutexFlags::WAIT => {
|
FutexFlags::WAIT => {
|
||||||
let timeout = timeout.read_if_not_null()?;
|
let timeout = timeout.read_if_not_null()?;
|
||||||
let duration: Duration = match timeout {
|
let duration: Duration = match timeout {
|
||||||
Some(T) => T.into(),
|
Some(t) => t.into(),
|
||||||
None => Duration::from_secs(0),
|
None => Duration::from_secs(0),
|
||||||
};
|
};
|
||||||
let into_lxerror = |e: ZxError| match e {
|
let into_lxerror = |e: ZxError| match e {
|
||||||
ZxError::BAD_STATE => LxError::EAGAIN,
|
ZxError::BAD_STATE => LxError::EAGAIN,
|
||||||
e => e.into(),
|
e => e.into(),
|
||||||
};
|
};
|
||||||
let future = futex.wait(val);
|
let future = futex.wait(val, false, self.thread.id() as i32);
|
||||||
let res = if duration.as_millis() == 0 {
|
let res = if duration.as_millis() == 0 {
|
||||||
future.await
|
future.await
|
||||||
} else {
|
} else {
|
||||||
warn!("duration: {:?}", duration);
|
warn!("duration: {:?}", duration);
|
||||||
pin_mut!(future);
|
pin_mut!(future);
|
||||||
self.thread
|
self.thread
|
||||||
.blocking_run(
|
.blocking_run(
|
||||||
future,
|
future,
|
||||||
ThreadState::BlockedFutex,
|
ThreadState::BlockedFutex,
|
||||||
timer_now() + duration,
|
timer_now() + duration,
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
};
|
};
|
||||||
match res {
|
match res {
|
||||||
Ok(_) => return Ok(0),
|
Ok(_) => return Ok(0),
|
||||||
Err(e) => return Err(into_lxerror(e)),
|
Err(e) => return Err(into_lxerror(e)),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
FutexFlags::WAKE => {
|
}
|
||||||
let woken_up_count = futex.wake(val as usize);
|
FutexFlags::WAKE => {
|
||||||
Ok(woken_up_count)
|
let woken_up_count = futex.wake(val as usize);
|
||||||
|
Ok(woken_up_count)
|
||||||
|
}
|
||||||
|
FutexFlags::LOCK_PI => {
|
||||||
|
let timeout = timeout.read_if_not_null()?;
|
||||||
|
let duration: Duration = match timeout {
|
||||||
|
Some(t) => t.into(),
|
||||||
|
None => Duration::from_secs(0),
|
||||||
|
};
|
||||||
|
let into_lxerror = |e: ZxError| match e {
|
||||||
|
ZxError::BAD_STATE => LxError::EAGAIN,
|
||||||
|
e => e.into(),
|
||||||
|
};
|
||||||
|
let future = futex.wait(val, true, self.thread.id() as i32);
|
||||||
|
let res = if duration.as_millis() == 0 {
|
||||||
|
future.await
|
||||||
|
} else {
|
||||||
|
warn!("duration: {:?}", duration);
|
||||||
|
pin_mut!(future);
|
||||||
|
self.thread
|
||||||
|
.blocking_run(
|
||||||
|
future,
|
||||||
|
ThreadState::BlockedFutex,
|
||||||
|
timer_now() + duration,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
};
|
||||||
|
match res {
|
||||||
|
Ok(_) => return Ok(0),
|
||||||
|
Err(e) => return Err(into_lxerror(e)),
|
||||||
}
|
}
|
||||||
_ => {
|
}
|
||||||
warn!("unsupported futex operation: {:?}", op);
|
FutexFlags::REQUEUE => {
|
||||||
Err(LxError::ENOPROTOOPT)
|
let requeue_futex = self.linux_process().get_futex(uaddr2);
|
||||||
|
let into_lxerror = |e: ZxError| match e {
|
||||||
|
ZxError::BAD_STATE => LxError::EAGAIN,
|
||||||
|
e => e.into(),
|
||||||
|
};
|
||||||
|
let res = futex.requeue(0, val as usize, val2, &requeue_futex, None, false);
|
||||||
|
match res {
|
||||||
|
Ok(_) => return Ok(0),
|
||||||
|
Err(e) => return Err(into_lxerror(e)),
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
None => Err(LxError::EAGAIN),
|
_ => {
|
||||||
|
warn!("unsupported futex operation: {:?}", op);
|
||||||
|
Err(LxError::ENOPROTOOPT)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,6 +264,8 @@ bitflags! {
|
||||||
/// wakes at most val of the waiters that are waiting on the futex word at the address uaddr.
|
/// wakes at most val of the waiters that are waiting on the futex word at the address uaddr.
|
||||||
const WAKE = 1;
|
const WAKE = 1;
|
||||||
///
|
///
|
||||||
|
const REQUEUE = 3;
|
||||||
|
///
|
||||||
const LOCK_PI = 6;
|
const LOCK_PI = 6;
|
||||||
///
|
///
|
||||||
const UNLOCK_PI = 7;
|
const UNLOCK_PI = 7;
|
||||||
|
|
|
@ -297,6 +297,7 @@ impl Syscall<'_> {
|
||||||
Ok(tid as usize)
|
Ok(tid as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get robust list.
|
||||||
pub fn sys_get_robust_list(
|
pub fn sys_get_robust_list(
|
||||||
&self,
|
&self,
|
||||||
pid: i32,
|
pid: i32,
|
||||||
|
@ -313,6 +314,7 @@ impl Syscall<'_> {
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set robust list.
|
||||||
pub fn sys_set_robust_list(&self, head: UserInPtr<RobustList>, len: usize) -> SysResult {
|
pub fn sys_set_robust_list(&self, head: UserInPtr<RobustList>, len: usize) -> SysResult {
|
||||||
warn!("in sys_set_robust_list");
|
warn!("in sys_set_robust_list");
|
||||||
if len != size_of::<RobustList>().into() {
|
if len != size_of::<RobustList>().into() {
|
||||||
|
|
|
@ -60,6 +60,7 @@ async fn run_user(thread: CurrentThread) {
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("back to user: thread id = {}", thread.id());
|
info!("back to user: thread id = {}", thread.id());
|
||||||
|
|
||||||
// run
|
// run
|
||||||
trace!("go to user: {:#x?}", ctx);
|
trace!("go to user: {:#x?}", ctx);
|
||||||
ctx.enter_uspace();
|
ctx.enter_uspace();
|
||||||
|
|
|
@ -62,7 +62,7 @@ pub fn boot_options() -> BootOptions {
|
||||||
#[cfg(feature = "linux")]
|
#[cfg(feature = "linux")]
|
||||||
root_proc: String::from(*options.get("ROOTPROC").unwrap_or(&"/bin/busybox?sh")),
|
root_proc: String::from(*options.get("ROOTPROC").unwrap_or(&"/bin/busybox?sh")),
|
||||||
// root_proc: String::from(*options.get("ROOTPROC")
|
// root_proc: String::from(*options.get("ROOTPROC")
|
||||||
// .unwrap_or(&"/libc-test/functional/pthread_robust.exe")),
|
// .unwrap_or(&"/libc-test/functional/pthread_mutex.exe")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,8 +57,13 @@ impl Futex {
|
||||||
///
|
///
|
||||||
/// [`wait_with_owner`]: Futex::wait_with_owner
|
/// [`wait_with_owner`]: Futex::wait_with_owner
|
||||||
/// [`wake`]: Futex::wake
|
/// [`wake`]: Futex::wake
|
||||||
pub fn wait(self: &Arc<Self>, current_value: u32) -> impl Future<Output = ZxResult> {
|
pub fn wait(
|
||||||
self.wait_with_owner(current_value, None, None)
|
self: &Arc<Self>,
|
||||||
|
current_value: u32,
|
||||||
|
lock_pi: bool,
|
||||||
|
thread_id: i32,
|
||||||
|
) -> impl Future<Output = ZxResult> {
|
||||||
|
self.wait_with_owner(current_value, None, None, lock_pi, thread_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wake some number of threads waiting on a futex.
|
/// Wake some number of threads waiting on a futex.
|
||||||
|
@ -117,12 +122,16 @@ impl Futex {
|
||||||
current_value: u32,
|
current_value: u32,
|
||||||
thread: Option<Arc<Thread>>,
|
thread: Option<Arc<Thread>>,
|
||||||
new_owner: Option<Arc<Thread>>,
|
new_owner: Option<Arc<Thread>>,
|
||||||
|
lock_pi: bool,
|
||||||
|
thread_id: i32,
|
||||||
) -> impl Future<Output = ZxResult> {
|
) -> impl Future<Output = ZxResult> {
|
||||||
#[must_use = "wait does nothing unless polled/`await`-ed"]
|
#[must_use = "wait does nothing unless polled/`await`-ed"]
|
||||||
struct FutexFuture {
|
struct FutexFuture {
|
||||||
waiter: Arc<Waiter>,
|
waiter: Arc<Waiter>,
|
||||||
current_value: u32,
|
current_value: u32,
|
||||||
new_owner: Option<Arc<Thread>>,
|
new_owner: Option<Arc<Thread>>,
|
||||||
|
lock_pi: bool,
|
||||||
|
thread_id: i32,
|
||||||
}
|
}
|
||||||
impl Future for FutexFuture {
|
impl Future for FutexFuture {
|
||||||
type Output = ZxResult;
|
type Output = ZxResult;
|
||||||
|
@ -133,15 +142,29 @@ impl Futex {
|
||||||
if inner.woken {
|
if inner.woken {
|
||||||
// set new owner on success
|
// set new owner on success
|
||||||
inner.futex.inner.lock().set_owner(self.new_owner.clone());
|
inner.futex.inner.lock().set_owner(self.new_owner.clone());
|
||||||
|
warn!("Futex Ready!!!");
|
||||||
return Poll::Ready(Ok(()));
|
return Poll::Ready(Ok(()));
|
||||||
}
|
}
|
||||||
// first time?
|
// first time?
|
||||||
if inner.waker.is_none() {
|
if inner.waker.is_none() {
|
||||||
// check value
|
// check value
|
||||||
let value = inner.futex.value.load(Ordering::SeqCst);
|
let value = inner.futex.value.load(Ordering::SeqCst);
|
||||||
if value as u32 != self.current_value {
|
if self.lock_pi {
|
||||||
warn!("Futex BAD STATE");
|
if value as u32 == 0 {
|
||||||
return Poll::Ready(Err(ZxError::BAD_STATE));
|
warn!("This is {}", self.thread_id);
|
||||||
|
inner.futex.value.store(self.thread_id, Ordering::SeqCst);
|
||||||
|
} else {
|
||||||
|
inner
|
||||||
|
.futex
|
||||||
|
.value
|
||||||
|
.store((value as u32 | 0x80000000) as i32, Ordering::SeqCst);
|
||||||
|
}
|
||||||
|
return Poll::Ready(Ok(()));
|
||||||
|
} else {
|
||||||
|
if value as u32 != self.current_value {
|
||||||
|
warn!("Futex BAD_STATE!!!");
|
||||||
|
return Poll::Ready(Err(ZxError::BAD_STATE));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// check new owner
|
// check new owner
|
||||||
let mut futex = inner.futex.inner.lock();
|
let mut futex = inner.futex.inner.lock();
|
||||||
|
@ -182,6 +205,8 @@ impl Futex {
|
||||||
}),
|
}),
|
||||||
current_value,
|
current_value,
|
||||||
new_owner,
|
new_owner,
|
||||||
|
lock_pi,
|
||||||
|
thread_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,11 +249,14 @@ impl Futex {
|
||||||
requeue_count: usize,
|
requeue_count: usize,
|
||||||
requeue_futex: &Arc<Futex>,
|
requeue_futex: &Arc<Futex>,
|
||||||
new_requeue_owner: Option<Arc<Thread>>,
|
new_requeue_owner: Option<Arc<Thread>>,
|
||||||
|
check_value: bool,
|
||||||
) -> ZxResult {
|
) -> ZxResult {
|
||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
// check value
|
if check_value {
|
||||||
if self.value.load(Ordering::SeqCst) != current_value {
|
// check value
|
||||||
return Err(ZxError::BAD_STATE);
|
if self.value.load(Ordering::SeqCst) != current_value {
|
||||||
|
return Err(ZxError::BAD_STATE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// wake
|
// wake
|
||||||
for _ in 0..wake_count {
|
for _ in 0..wake_count {
|
||||||
|
|
|
@ -74,6 +74,7 @@ impl Syscall<'_> {
|
||||||
requeue_count as usize,
|
requeue_count as usize,
|
||||||
&requeue_futex,
|
&requeue_futex,
|
||||||
new_requeue_owner,
|
new_requeue_owner,
|
||||||
|
true,
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue