Format
This commit is contained in:
+1
-1
@@ -46,10 +46,10 @@ pub mod sys_statvfs;
|
||||
pub mod sys_time;
|
||||
pub mod sys_timeb;
|
||||
//pub mod sys_times;
|
||||
pub mod sys_user;
|
||||
pub mod _wctype;
|
||||
pub mod sys_uio;
|
||||
pub mod sys_un;
|
||||
pub mod sys_user;
|
||||
pub mod sys_utsname;
|
||||
pub mod sys_wait;
|
||||
pub mod termios;
|
||||
|
||||
@@ -5,8 +5,8 @@ use header::errno;
|
||||
use header::fcntl::*;
|
||||
use header::string::strchr;
|
||||
use io::LineWriter;
|
||||
use platform::types::*;
|
||||
use platform;
|
||||
use platform::types::*;
|
||||
use sync::Mutex;
|
||||
|
||||
use super::constants::*;
|
||||
|
||||
@@ -14,10 +14,10 @@ use header::errno::{self, STR_ERROR};
|
||||
use header::string::{self, strlen};
|
||||
use header::{fcntl, stdlib, unistd};
|
||||
use io::{self, BufRead, LineWriter, Read, Write};
|
||||
use platform::types::*;
|
||||
use platform::{Pal, Sys};
|
||||
use platform::{errno, WriteByte};
|
||||
use platform;
|
||||
use platform::types::*;
|
||||
use platform::{errno, WriteByte};
|
||||
use platform::{Pal, Sys};
|
||||
use sync::Mutex;
|
||||
|
||||
pub use self::constants::*;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! ptrace compatibility layer for Redox OS
|
||||
|
||||
use platform::types::*;
|
||||
use platform::{Sys, PalPtrace};
|
||||
use platform::{PalPtrace, Sys};
|
||||
|
||||
pub const PTRACE_PEEKTEXT: c_int = 1;
|
||||
pub const PTRACE_PEEKDATA: c_int = 2;
|
||||
|
||||
@@ -4,7 +4,7 @@ use platform::types::*;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct user_fpregs_struct {
|
||||
cwd: u16,
|
||||
cwd: u16,
|
||||
swd: u16,
|
||||
ftw: u16,
|
||||
fop: u16,
|
||||
@@ -12,14 +12,14 @@ pub struct user_fpregs_struct {
|
||||
rdp: u64,
|
||||
mxcsr: u32,
|
||||
mxcr_mask: u32,
|
||||
st_space: [u32; 32],
|
||||
st_space: [u32; 32],
|
||||
xmm_space: [u32; 64],
|
||||
padding: [u32; 24]
|
||||
padding: [u32; 24],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct user_regs_struct {
|
||||
r15: c_ulong,
|
||||
r15: c_ulong,
|
||||
r14: c_ulong,
|
||||
r13: c_ulong,
|
||||
r12: c_ulong,
|
||||
@@ -29,14 +29,14 @@ pub struct user_regs_struct {
|
||||
r10: c_ulong,
|
||||
r9: c_ulong,
|
||||
r8: c_ulong,
|
||||
rax: c_ulong,
|
||||
rax: c_ulong,
|
||||
rcx: c_ulong,
|
||||
rdx: c_ulong,
|
||||
rsi: c_ulong,
|
||||
rdi: c_ulong,
|
||||
orig_rax: c_ulong,
|
||||
rip: c_ulong,
|
||||
cs: c_ulong,
|
||||
cs: c_ulong,
|
||||
eflags: c_ulong,
|
||||
rsp: c_ulong,
|
||||
ss: c_ulong,
|
||||
@@ -45,8 +45,12 @@ pub struct user_regs_struct {
|
||||
ds: c_ulong,
|
||||
es: c_ulong,
|
||||
fs: c_ulong,
|
||||
gs: c_ulong
|
||||
gs: c_ulong,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn _cbindgen_only_generates_structs_if_they_are_mentioned_which_is_dumb(a: user_fpregs_struct, b: user_regs_struct) {}
|
||||
pub extern "C" fn _cbindgen_only_generates_structs_if_they_are_mentioned_which_is_dumb(
|
||||
a: user_fpregs_struct,
|
||||
b: user_regs_struct,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -11,9 +11,7 @@ use crate::sync::{Mutex, Once};
|
||||
use alloc::collections::BTreeMap;
|
||||
|
||||
#[derive(Default)]
|
||||
struct State {
|
||||
|
||||
}
|
||||
struct State {}
|
||||
|
||||
static STATE: Once<Mutex<State>> = Once::new();
|
||||
|
||||
|
||||
+19
-13
@@ -6,8 +6,8 @@ pub use self::once::Once;
|
||||
|
||||
use core::cell::UnsafeCell;
|
||||
use core::ops::Deref;
|
||||
use core::sync::atomic::AtomicI32 as AtomicInt;
|
||||
use core::sync::atomic;
|
||||
use core::sync::atomic::AtomicI32 as AtomicInt;
|
||||
use platform::types::*;
|
||||
use platform::{Pal, Sys};
|
||||
|
||||
@@ -18,28 +18,36 @@ const FUTEX_WAKE: c_int = 1;
|
||||
enum AttemptStatus {
|
||||
Desired,
|
||||
Waiting,
|
||||
Other
|
||||
Other,
|
||||
}
|
||||
|
||||
/// Convenient wrapper around the "futex" system call for
|
||||
/// synchronization implementations
|
||||
struct AtomicLock {
|
||||
atomic: UnsafeCell<AtomicInt>
|
||||
atomic: UnsafeCell<AtomicInt>,
|
||||
}
|
||||
impl AtomicLock {
|
||||
pub const fn new(value: c_int) -> Self {
|
||||
Self {
|
||||
atomic: UnsafeCell::new(AtomicInt::new(value))
|
||||
atomic: UnsafeCell::new(AtomicInt::new(value)),
|
||||
}
|
||||
}
|
||||
pub fn notify_one(&self) {
|
||||
Sys::futex(unsafe { &mut *self.atomic.get() }.get_mut(), FUTEX_WAKE, 1);
|
||||
}
|
||||
pub fn notify_all(&self) {
|
||||
Sys::futex(unsafe { &mut *self.atomic.get() }.get_mut(), FUTEX_WAKE, c_int::max_value());
|
||||
Sys::futex(
|
||||
unsafe { &mut *self.atomic.get() }.get_mut(),
|
||||
FUTEX_WAKE,
|
||||
c_int::max_value(),
|
||||
);
|
||||
}
|
||||
pub fn wait_if(&self, value: c_int) {
|
||||
Sys::futex(unsafe { &mut *self.atomic.get() }.get_mut(), FUTEX_WAIT, value);
|
||||
Sys::futex(
|
||||
unsafe { &mut *self.atomic.get() }.get_mut(),
|
||||
FUTEX_WAIT,
|
||||
value,
|
||||
);
|
||||
}
|
||||
/// A general way to efficiently wait for what might be a long time, using two closures:
|
||||
///
|
||||
@@ -63,7 +71,7 @@ impl AtomicLock {
|
||||
pub fn wait_until<F1, F2>(&self, attempt: F1, mark_long: F2, long: c_int)
|
||||
where
|
||||
F1: Fn(&AtomicInt) -> AttemptStatus,
|
||||
F2: Fn(&AtomicInt) -> AttemptStatus
|
||||
F2: Fn(&AtomicInt) -> AttemptStatus,
|
||||
{
|
||||
// First, try spinning for really short durations
|
||||
for _ in 0..999 {
|
||||
@@ -84,9 +92,9 @@ impl AtomicLock {
|
||||
}
|
||||
|
||||
if
|
||||
// If we or somebody else already initiated a long
|
||||
// wait, OR
|
||||
previous == AttemptStatus::Waiting ||
|
||||
// If we or somebody else already initiated a long
|
||||
// wait, OR
|
||||
previous == AttemptStatus::Waiting ||
|
||||
// Otherwise, unless our attempt to initiate a long
|
||||
// wait informed us that we might be done waiting
|
||||
mark_long(self) != AttemptStatus::Desired
|
||||
@@ -102,8 +110,6 @@ impl Deref for AtomicLock {
|
||||
type Target = AtomicInt;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe {
|
||||
&*self.atomic.get()
|
||||
}
|
||||
unsafe { &*self.atomic.get() }
|
||||
}
|
||||
}
|
||||
|
||||
+11
-7
@@ -5,8 +5,8 @@ use core::sync::atomic::Ordering::SeqCst;
|
||||
use platform::types::*;
|
||||
|
||||
const UNLOCKED: c_int = 0;
|
||||
const LOCKED: c_int = 1;
|
||||
const WAITING: c_int = 2;
|
||||
const LOCKED: c_int = 1;
|
||||
const WAITING: c_int = 2;
|
||||
|
||||
pub struct Mutex<T> {
|
||||
lock: AtomicLock,
|
||||
@@ -40,7 +40,8 @@ impl<T> Mutex<T> {
|
||||
/// on failure. You should probably not worry about this, it's used for
|
||||
/// internal optimizations.
|
||||
pub unsafe fn manual_try_lock(&self) -> Result<&mut T, c_int> {
|
||||
self.lock.compare_exchange(UNLOCKED, LOCKED, SeqCst, SeqCst)
|
||||
self.lock
|
||||
.compare_exchange(UNLOCKED, LOCKED, SeqCst, SeqCst)
|
||||
.map(|_| &mut *self.content.get())
|
||||
}
|
||||
/// Lock the mutex, returning the inner content. After doing this, it's
|
||||
@@ -53,15 +54,18 @@ impl<T> Mutex<T> {
|
||||
.map(|_| AttemptStatus::Desired)
|
||||
.unwrap_or_else(|e| match e {
|
||||
WAITING => AttemptStatus::Waiting,
|
||||
_ => AttemptStatus::Other
|
||||
_ => AttemptStatus::Other,
|
||||
})
|
||||
},
|
||||
|lock| match lock.compare_exchange_weak(LOCKED, WAITING, SeqCst, SeqCst).unwrap_or_else(|e| e) {
|
||||
|lock| match lock
|
||||
.compare_exchange_weak(LOCKED, WAITING, SeqCst, SeqCst)
|
||||
.unwrap_or_else(|e| e)
|
||||
{
|
||||
UNLOCKED => AttemptStatus::Desired,
|
||||
WAITING => AttemptStatus::Waiting,
|
||||
_ => AttemptStatus::Other
|
||||
_ => AttemptStatus::Other,
|
||||
},
|
||||
WAITING
|
||||
WAITING,
|
||||
);
|
||||
&mut *self.content.get()
|
||||
}
|
||||
|
||||
+21
-16
@@ -5,13 +5,13 @@ use core::sync::atomic::Ordering::SeqCst;
|
||||
use platform::types::*;
|
||||
|
||||
const UNINITIALIZED: c_int = 0;
|
||||
const INITIALIZING: c_int = 1;
|
||||
const WAITING: c_int = 2;
|
||||
const INITIALIZED: c_int = 3;
|
||||
const INITIALIZING: c_int = 1;
|
||||
const WAITING: c_int = 2;
|
||||
const INITIALIZED: c_int = 3;
|
||||
|
||||
pub struct Once<T> {
|
||||
status: AtomicLock,
|
||||
data: UnsafeCell<MaybeUninit<T>>
|
||||
data: UnsafeCell<MaybeUninit<T>>,
|
||||
}
|
||||
unsafe impl<T: Send> Send for Once<T> {}
|
||||
unsafe impl<T: Send> Sync for Once<T> {}
|
||||
@@ -19,13 +19,17 @@ impl<T> Once<T> {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
status: AtomicLock::new(UNINITIALIZED),
|
||||
data: UnsafeCell::new(MaybeUninit::uninit())
|
||||
data: UnsafeCell::new(MaybeUninit::uninit()),
|
||||
}
|
||||
}
|
||||
pub fn call_once<F>(&self, f: F) -> &mut T
|
||||
where F: FnOnce() -> T
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
{
|
||||
match self.status.compare_and_swap(UNINITIALIZED, INITIALIZING, SeqCst) {
|
||||
match self
|
||||
.status
|
||||
.compare_and_swap(UNINITIALIZED, INITIALIZING, SeqCst)
|
||||
{
|
||||
UNINITIALIZED => {
|
||||
// We now have a lock, let's initiate things!
|
||||
let ret = unsafe { &mut *self.data.get() }.write(f());
|
||||
@@ -35,28 +39,29 @@ impl<T> Once<T> {
|
||||
// At least one thread is waiting on this to finish
|
||||
self.status.notify_all();
|
||||
}
|
||||
},
|
||||
}
|
||||
INITIALIZING | WAITING => self.status.wait_until(
|
||||
|lock| match lock.load(SeqCst) {
|
||||
WAITING => AttemptStatus::Waiting,
|
||||
INITIALIZED => AttemptStatus::Desired,
|
||||
_ => AttemptStatus::Other
|
||||
_ => AttemptStatus::Other,
|
||||
},
|
||||
|lock| match lock.compare_exchange_weak(INITIALIZING, WAITING, SeqCst, SeqCst).unwrap_or_else(|e| e) {
|
||||
|lock| match lock
|
||||
.compare_exchange_weak(INITIALIZING, WAITING, SeqCst, SeqCst)
|
||||
.unwrap_or_else(|e| e)
|
||||
{
|
||||
WAITING => AttemptStatus::Waiting,
|
||||
INITIALIZED => AttemptStatus::Desired,
|
||||
_ => AttemptStatus::Other
|
||||
_ => AttemptStatus::Other,
|
||||
},
|
||||
WAITING
|
||||
WAITING,
|
||||
),
|
||||
INITIALIZED => (),
|
||||
_ => unreachable!("invalid state for Once<T>")
|
||||
_ => unreachable!("invalid state for Once<T>"),
|
||||
}
|
||||
|
||||
// At this point the data must be initialized!
|
||||
unsafe {
|
||||
&mut *(&mut *self.data.get()).as_mut_ptr()
|
||||
}
|
||||
unsafe { &mut *(&mut *self.data.get()).as_mut_ptr() }
|
||||
}
|
||||
}
|
||||
impl<T> Default for Once<T> {
|
||||
|
||||
Reference in New Issue
Block a user