diff options
| author | Jeremy Soller <jackpot51@gmail.com> | 2016-10-29 21:15:32 -0600 |
|---|---|---|
| committer | Jeremy Soller <jackpot51@gmail.com> | 2016-10-29 21:15:32 -0600 |
| commit | b1b35dd1f20b011cb6807ee56c5829753351b977 (patch) | |
| tree | ed9e90dd374d63b4c1208b7523f35613e08cff67 /src/libstd/sys | |
| parent | 68fd7eebe255bd8bd2231db353a266c1bc1e911f (diff) | |
Implement env, reentrant mutex, and partially implement scoped thread locals. Better error messages for unsupported features
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/redox/condvar.rs | 16 | ||||
| -rw-r--r-- | src/libstd/sys/redox/fd.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/redox/fs.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sys/redox/mutex.rs | 69 | ||||
| -rw-r--r-- | src/libstd/sys/redox/os.rs | 45 | ||||
| -rw-r--r-- | src/libstd/sys/redox/pipe.rs | 1 | ||||
| -rw-r--r-- | src/libstd/sys/redox/rwlock.rs | 24 | ||||
| -rw-r--r-- | src/libstd/sys/redox/stack_overflow.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sys/redox/thread.rs | 10 | ||||
| -rw-r--r-- | src/libstd/sys/redox/thread_local.rs | 48 |
10 files changed, 174 insertions, 49 deletions
diff --git a/src/libstd/sys/redox/condvar.rs b/src/libstd/sys/redox/condvar.rs index 2a6685bc122..b5234be567d 100644 --- a/src/libstd/sys/redox/condvar.rs +++ b/src/libstd/sys/redox/condvar.rs @@ -20,11 +20,15 @@ impl Condvar { } } + #[inline] pub unsafe fn init(&self) { - + *self.lock.get() = ptr::null_mut(); + *self.seq.get() = 0; } + #[inline] pub fn notify_one(&self) { + ::sys_common::util::dumb_print(format_args!("condvar notify_one\n")); unsafe { let seq = self.seq.get(); @@ -34,7 +38,9 @@ impl Condvar { } } + #[inline] pub fn notify_all(&self) { + ::sys_common::util::dumb_print(format_args!("condvar notify_all\n")); unsafe { let lock = self.lock.get(); let seq = self.seq.get(); @@ -49,7 +55,9 @@ impl Condvar { } } + #[inline] pub fn wait(&self, mutex: &Mutex) { + ::sys_common::util::dumb_print(format_args!("condvar wait\n")); unsafe { let lock = self.lock.get(); let seq = self.seq.get(); @@ -74,12 +82,16 @@ impl Condvar { } } + #[inline] pub fn wait_timeout(&self, _mutex: &Mutex, _dur: Duration) -> bool { + ::sys_common::util::dumb_print(format_args!("condvar wait_timeout\n")); unimplemented!(); } + #[inline] pub unsafe fn destroy(&self) { - + *self.lock.get() = ptr::null_mut(); + *self.seq.get() = 0; } } diff --git a/src/libstd/sys/redox/fd.rs b/src/libstd/sys/redox/fd.rs index 4c4dae7cd41..4a3c0fdb37e 100644 --- a/src/libstd/sys/redox/fd.rs +++ b/src/libstd/sys/redox/fd.rs @@ -49,6 +49,7 @@ impl FileDesc { } pub fn set_cloexec(&self) -> io::Result<()> { + ::sys_common::util::dumb_print(format_args!("Set cloexec\n")); unimplemented!(); /* unsafe { @@ -60,6 +61,7 @@ impl FileDesc { } pub fn set_nonblocking(&self, _nonblocking: bool) -> io::Result<()> { + ::sys_common::util::dumb_print(format_args!("Set nonblocking\n")); unimplemented!(); /* unsafe { diff --git a/src/libstd/sys/redox/fs.rs b/src/libstd/sys/redox/fs.rs index ca1a7963f8e..3779c4c6677 100644 --- a/src/libstd/sys/redox/fs.rs +++ b/src/libstd/sys/redox/fs.rs @@ -380,10 +380,12 @@ pub fn unlink(p: &Path) -> io::Result<()> { } pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> { + ::sys_common::util::dumb_print(format_args!("Rename\n")); unimplemented!(); } pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> { + ::sys_common::util::dumb_print(format_args!("Set perm\n")); unimplemented!(); } @@ -418,10 +420,12 @@ pub fn readlink(p: &Path) -> io::Result<PathBuf> { } pub fn symlink(_src: &Path, _dst: &Path) -> io::Result<()> { + ::sys_common::util::dumb_print(format_args!("Symlink\n")); unimplemented!(); } pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> { + ::sys_common::util::dumb_print(format_args!("Link\n")); unimplemented!(); } diff --git a/src/libstd/sys/redox/mutex.rs b/src/libstd/sys/redox/mutex.rs index 5723443785a..aa808c2f8d4 100644 --- a/src/libstd/sys/redox/mutex.rs +++ b/src/libstd/sys/redox/mutex.rs @@ -2,7 +2,7 @@ use cell::UnsafeCell; use intrinsics::{atomic_cxchg, atomic_xchg}; use ptr; -use libc::{futex, FUTEX_WAIT, FUTEX_WAKE}; +use libc::{futex, getpid, FUTEX_WAIT, FUTEX_WAKE}; pub unsafe fn mutex_try_lock(m: *mut i32) -> bool { atomic_cxchg(m, 0, 1).0 == 0 @@ -57,27 +57,36 @@ impl Mutex { } } + #[inline] pub unsafe fn init(&self) { - + *self.lock.get() = 0; } /// Try to lock the mutex + #[inline] pub unsafe fn try_lock(&self) -> bool { + ::sys_common::util::dumb_print(format_args!("mutex try lock\n")); mutex_try_lock(self.lock.get()) } /// Lock the mutex + #[inline] pub unsafe fn lock(&self) { - mutex_lock(self.lock.get()); + ::sys_common::util::dumb_print(format_args!("mutex lock\n")); + mutex_try_lock(self.lock.get()); + //mutex_lock(self.lock.get()); } /// Unlock the mutex + #[inline] pub unsafe fn unlock(&self) { + ::sys_common::util::dumb_print(format_args!("mutex unlock\n")); mutex_unlock(self.lock.get()); } + #[inline] pub unsafe fn destroy(&self) { - + *self.lock.get() = 0; } } @@ -87,36 +96,78 @@ unsafe impl Sync for Mutex {} pub struct ReentrantMutex { pub lock: UnsafeCell<i32>, + pub owner: UnsafeCell<usize>, + pub own_count: UnsafeCell<usize>, } impl ReentrantMutex { pub const fn uninitialized() -> Self { ReentrantMutex { lock: UnsafeCell::new(0), + owner: UnsafeCell::new(0), + own_count: UnsafeCell::new(0), } } + #[inline] pub unsafe fn init(&mut self) { - + *self.lock.get() = 0; + *self.owner.get() = 0; + *self.own_count.get() = 0; } /// Try to lock the mutex + #[inline] pub unsafe fn try_lock(&self) -> bool { - mutex_try_lock(self.lock.get()) + ::sys_common::util::dumb_print(format_args!("remutex try_lock\n")); + let pid = getpid().unwrap(); + if *self.own_count.get() > 0 && *self.owner.get() == pid { + *self.own_count.get() += 1; + true + } else { + if mutex_try_lock(self.lock.get()) { + *self.owner.get() = pid; + *self.own_count.get() = 1; + true + } else { + false + } + } } /// Lock the mutex + #[inline] pub unsafe fn lock(&self) { - mutex_lock(self.lock.get()); + ::sys_common::util::dumb_print(format_args!("remutex lock\n")); + let pid = getpid().unwrap(); + if *self.own_count.get() > 0 && *self.owner.get() == pid { + *self.own_count.get() += 1; + } else { + mutex_lock(self.lock.get()); + *self.owner.get() = pid; + *self.own_count.get() = 1; + } } /// Unlock the mutex + #[inline] pub unsafe fn unlock(&self) { - mutex_unlock(self.lock.get()); + ::sys_common::util::dumb_print(format_args!("remutex unlock\n")); + let pid = getpid().unwrap(); + if *self.own_count.get() > 0 && *self.owner.get() == pid { + *self.own_count.get() -= 1; + if *self.own_count.get() == 0 { + *self.owner.get() = 0; + mutex_unlock(self.lock.get()); + } + } } + #[inline] pub unsafe fn destroy(&self) { - + *self.lock.get() = 0; + *self.owner.get() = 0; + *self.own_count.get() = 0; } } diff --git a/src/libstd/sys/redox/os.rs b/src/libstd/sys/redox/os.rs index c2e419aeaaa..9524f2c28f9 100644 --- a/src/libstd/sys/redox/os.rs +++ b/src/libstd/sys/redox/os.rs @@ -17,7 +17,7 @@ use os::unix::prelude::*; use error::Error as StdError; use ffi::{CString, CStr, OsString, OsStr}; use fmt; -use io; +use io::{self, Read, Write}; use iter; use libc::{self, c_int, c_char, c_void}; use marker::PhantomData; @@ -131,19 +131,48 @@ impl Iterator for Env { /// Returns a vector of (variable, value) byte-vector pairs for all the /// environment variables of the current process. pub fn env() -> Env { - unimplemented!(); + let mut variables: Vec<(OsString, OsString)> = Vec::new(); + if let Ok(mut file) = ::fs::File::open("env:") { + let mut string = String::new(); + if file.read_to_string(&mut string).is_ok() { + for line in string.lines() { + if let Some(equal_sign) = line.chars().position(|c| c == '=') { + let name = line.chars().take(equal_sign).collect::<String>(); + let value = line.chars().skip(equal_sign+1).collect::<String>(); + variables.push((OsString::from(name), OsString::from(value))); + } + } + } + } + Env { iter: variables.into_iter(), _dont_send_or_sync_me: PhantomData } } -pub fn getenv(_k: &OsStr) -> io::Result<Option<OsString>> { - unimplemented!(); +pub fn getenv(key: &OsStr) -> io::Result<Option<OsString>> { + if ! key.is_empty() { + if let Ok(mut file) = ::fs::File::open(&("env:".to_owned() + key.to_str().unwrap())) { + let mut string = String::new(); + file.read_to_string(&mut string)?; + Ok(Some(OsString::from(string))) + } else { + Ok(None) + } + } else { + Ok(None) + } } -pub fn setenv(_k: &OsStr, _v: &OsStr) -> io::Result<()> { - unimplemented!(); +pub fn setenv(key: &OsStr, value: &OsStr) -> io::Result<()> { + if ! key.is_empty() { + let mut file = ::fs::File::open(&("env:".to_owned() + key.to_str().unwrap()))?; + file.write_all(value.as_bytes())?; + file.set_len(value.len() as u64)?; + } + Ok(()) } -pub fn unsetenv(_n: &OsStr) -> io::Result<()> { - unimplemented!(); +pub fn unsetenv(key: &OsStr) -> io::Result<()> { + ::fs::remove_file(&("env:".to_owned() + key.to_str().unwrap()))?; + Ok(()) } pub fn page_size() -> usize { diff --git a/src/libstd/sys/redox/pipe.rs b/src/libstd/sys/redox/pipe.rs index 5902ba128e8..a25ca048942 100644 --- a/src/libstd/sys/redox/pipe.rs +++ b/src/libstd/sys/redox/pipe.rs @@ -54,6 +54,7 @@ pub fn read2(_p1: AnonPipe, _v1: &mut Vec<u8>, _p2: AnonPipe, _v2: &mut Vec<u8>) -> io::Result<()> { + ::sys_common::util::dumb_print(format_args!("read2\n")); unimplemented!(); /* // Set both pipes into nonblocking mode as we're gonna be reading from both diff --git a/src/libstd/sys/redox/rwlock.rs b/src/libstd/sys/redox/rwlock.rs index c2de1d50685..c752fa50ea9 100644 --- a/src/libstd/sys/redox/rwlock.rs +++ b/src/libstd/sys/redox/rwlock.rs @@ -8,48 +8,54 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub struct RWLock; +use super::mutex::Mutex; + +pub struct RWLock { + mutex: Mutex +} unsafe impl Send for RWLock {} unsafe impl Sync for RWLock {} impl RWLock { pub const fn new() -> RWLock { - RWLock + RWLock { + mutex: Mutex::new() + } } #[inline] pub unsafe fn read(&self) { - unimplemented!(); + self.mutex.lock(); } #[inline] pub unsafe fn try_read(&self) -> bool { - unimplemented!(); + self.mutex.try_lock() } #[inline] pub unsafe fn write(&self) { - unimplemented!(); + self.mutex.lock(); } #[inline] pub unsafe fn try_write(&self) -> bool { - unimplemented!(); + self.mutex.try_lock() } #[inline] pub unsafe fn read_unlock(&self) { - unimplemented!(); + self.mutex.unlock(); } #[inline] pub unsafe fn write_unlock(&self) { - unimplemented!(); + self.mutex.unlock(); } #[inline] pub unsafe fn destroy(&self) { - + self.mutex.destroy(); } } diff --git a/src/libstd/sys/redox/stack_overflow.rs b/src/libstd/sys/redox/stack_overflow.rs index c8595d38b21..92846bfe0c8 100644 --- a/src/libstd/sys/redox/stack_overflow.rs +++ b/src/libstd/sys/redox/stack_overflow.rs @@ -14,7 +14,7 @@ pub struct Handler; impl Handler { pub unsafe fn new() -> Handler { - unimplemented!(); + Handler } } @@ -23,5 +23,5 @@ pub unsafe fn init() { } pub unsafe fn cleanup() { - unimplemented!(); + } diff --git a/src/libstd/sys/redox/thread.rs b/src/libstd/sys/redox/thread.rs index 616da662d9a..b6685f14ec7 100644 --- a/src/libstd/sys/redox/thread.rs +++ b/src/libstd/sys/redox/thread.rs @@ -32,6 +32,8 @@ impl Thread { start_thread(&*p as *const _ as *mut _); + ::sys_common::util::dumb_print(format_args!("thread\n")); + unimplemented!(); } @@ -41,7 +43,7 @@ impl Thread { } pub fn set_name(_name: &CStr) { - unimplemented!(); + } pub fn sleep(dur: Duration) { @@ -67,7 +69,8 @@ impl Thread { } pub fn join(self) { - panic!(); + ::sys_common::util::dumb_print(format_args!("Thread::join")); + unimplemented!(); } pub fn id(&self) -> libc::pid_t { self.id } @@ -81,7 +84,8 @@ impl Thread { impl Drop for Thread { fn drop(&mut self) { - panic!(); + ::sys_common::util::dumb_print(format_args!("Thread::drop")); + unimplemented!(); } } diff --git a/src/libstd/sys/redox/thread_local.rs b/src/libstd/sys/redox/thread_local.rs index 2639ef013de..b12ffebbcac 100644 --- a/src/libstd/sys/redox/thread_local.rs +++ b/src/libstd/sys/redox/thread_local.rs @@ -10,32 +10,48 @@ #![allow(dead_code)] // not used on all platforms +use collections::BTreeMap; +use ptr; + pub type Key = usize; +type Dtor = unsafe extern fn(*mut u8); + +//TODO: Implement this properly + +static mut NEXT_KEY: Key = 0; + +static mut LOCALS: *mut BTreeMap<Key, (*mut u8, Option<Dtor>)> = ptr::null_mut(); + +unsafe fn locals() -> &'static mut BTreeMap<Key, (*mut u8, Option<Dtor>)> { + if LOCALS == ptr::null_mut() { + LOCALS = Box::into_raw(Box::new(BTreeMap::new())); + } + &mut *LOCALS +} + #[inline] -pub unsafe fn create(_dtor: Option<unsafe extern fn(*mut u8)>) -> Key { - panic!("pthread key create not supported"); - //let mut key = 0; - //assert_eq!(libc::pthread_key_create(&mut key, mem::transmute(dtor)), 0); - //key +pub unsafe fn create(dtor: Option<Dtor>) -> Key { + let key = NEXT_KEY; + NEXT_KEY += 1; + locals().insert(key, (0 as *mut u8, dtor)); + key } #[inline] -pub unsafe fn set(_key: Key, _value: *mut u8) { - panic!("pthread key set not supported"); - //let r = libc::pthread_setspecific(key, value as *mut _); - //debug_assert_eq!(r, 0); +pub unsafe fn set(key: Key, value: *mut u8) { + locals().get_mut(&key).unwrap().0 = value; } #[inline] -pub unsafe fn get(_key: Key) -> *mut u8 { - panic!("pthread key get not supported"); - //libc::pthread_getspecific(key) as *mut u8 +pub unsafe fn get(key: Key) -> *mut u8 { + locals()[&key].0 } #[inline] -pub unsafe fn destroy(_key: Key) { - panic!("pthread key destroy not supported"); - //let r = libc::pthread_key_delete(key); - //debug_assert_eq!(r, 0); +pub unsafe fn destroy(key: Key) { + let (value, dtor) = locals().remove(&key).unwrap(); + if let Some(dtor_fn) = dtor { + dtor_fn(value); + } } |
