]> git.lizzy.rs Git - rust.git/commitdiff
Implement env, reentrant mutex, and partially implement scoped thread locals. Better...
authorJeremy Soller <jackpot51@gmail.com>
Sun, 30 Oct 2016 03:15:32 +0000 (21:15 -0600)
committerJeremy Soller <jackpot51@gmail.com>
Sun, 30 Oct 2016 03:15:32 +0000 (21:15 -0600)
src/libstd/sys/redox/condvar.rs
src/libstd/sys/redox/fd.rs
src/libstd/sys/redox/fs.rs
src/libstd/sys/redox/mutex.rs
src/libstd/sys/redox/os.rs
src/libstd/sys/redox/pipe.rs
src/libstd/sys/redox/rwlock.rs
src/libstd/sys/redox/stack_overflow.rs
src/libstd/sys/redox/thread.rs
src/libstd/sys/redox/thread_local.rs

index 2a6685bc12245dcbd276968ed6979810ec851a4c..b5234be567dd52b55f17f98b471e8f555e3cf806 100644 (file)
@@ -20,11 +20,15 @@ pub const fn new() -> 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 @@ pub fn notify_one(&self) {
         }
     }
 
+    #[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 @@ pub fn notify_all(&self) {
         }
     }
 
+    #[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 @@ pub fn wait(&self, mutex: &Mutex) {
         }
     }
 
+    #[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;
     }
 }
 
index 4c4dae7cd418b73798e9eea0d8e4fc616f5b431d..4a3c0fdb37e966ccb8b507eb6d1733c3b777557d 100644 (file)
@@ -49,6 +49,7 @@ pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
     }
 
     pub fn set_cloexec(&self) -> io::Result<()> {
+        ::sys_common::util::dumb_print(format_args!("Set cloexec\n"));
         unimplemented!();
         /*
         unsafe {
@@ -60,6 +61,7 @@ pub fn set_cloexec(&self) -> io::Result<()> {
     }
 
     pub fn set_nonblocking(&self, _nonblocking: bool) -> io::Result<()> {
+        ::sys_common::util::dumb_print(format_args!("Set nonblocking\n"));
         unimplemented!();
         /*
         unsafe {
index ca1a7963f8e6ec56aff61a47cefc719c18d5ebaa..3779c4c66775eaaef89899aa71b9703d1ed4f0e4 100644 (file)
@@ -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!();
 }
 
index 5723443785a0d68e90608c4b9c096f7e4d95cbfe..aa808c2f8d45b60fdab13f8481f0fb8c9878de49 100644 (file)
@@ -2,7 +2,7 @@
 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 @@ pub const fn new() -> Self {
         }
     }
 
+    #[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;
     }
 }
 
index c2e419aeaaa5ae925ddd1dff21acd5c2bed1f8da..9524f2c28f9da9a8b89d3ffccf7bbe76fbbf5e9c 100644 (file)
@@ -17,7 +17,7 @@
 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 @@ fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
 /// 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 {
index 5902ba128e8d7168ec63dfd295c8a4e215cb2ebb..a25ca048942727ad212b2b5fe8eb59b124a862aa 100644 (file)
@@ -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
index c2de1d50685f27e6056121d79f5b68de9f7d40d2..c752fa50ea9ddef6884beb8b7c598f9d6ef5e40c 100644 (file)
@@ -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();
     }
 }
index c8595d38b21c73bb9c59e4c4064efe661a61d90a..92846bfe0c8d115a4bd43c0a5a3fff12cb8fb9a6 100644 (file)
@@ -14,7 +14,7 @@
 
 impl Handler {
     pub unsafe fn new() -> Handler {
-        unimplemented!();
+        Handler
     }
 }
 
@@ -23,5 +23,5 @@ pub unsafe fn init() {
 }
 
 pub unsafe fn cleanup() {
-    unimplemented!();
+    
 }
index 616da662d9ac1f1d1586fad2718d98a3c6a955b5..b6685f14ec724e40952a7e35ba0ff3163e09abeb 100644 (file)
@@ -32,6 +32,8 @@ pub unsafe fn new<'a>(_stack: usize, p: Box<FnBox() + 'a>) -> io::Result<Thread>
 
         start_thread(&*p as *const _ as *mut _);
 
+        ::sys_common::util::dumb_print(format_args!("thread\n"));
+
         unimplemented!();
     }
 
@@ -41,7 +43,7 @@ pub fn yield_now() {
     }
 
     pub fn set_name(_name: &CStr) {
-        unimplemented!();
+
     }
 
     pub fn sleep(dur: Duration) {
@@ -67,7 +69,8 @@ pub fn sleep(dur: Duration) {
     }
 
     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 @@ pub fn into_id(self) -> libc::pid_t {
 
 impl Drop for Thread {
     fn drop(&mut self) {
-        panic!();
+        ::sys_common::util::dumb_print(format_args!("Thread::drop"));
+        unimplemented!();
     }
 }
 
index 2639ef013dee38817e23326f359460db9f2f0071..b12ffebbcac1d6a7c370f5be1ce2247b5698bf00 100644 (file)
 
 #![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);
+    }
 }