}
}
+ #[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();
}
}
+ #[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();
}
}
+ #[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();
}
}
+ #[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;
}
}
}
pub fn set_cloexec(&self) -> io::Result<()> {
+ ::sys_common::util::dumb_print(format_args!("Set cloexec\n"));
unimplemented!();
/*
unsafe {
}
pub fn set_nonblocking(&self, _nonblocking: bool) -> io::Result<()> {
+ ::sys_common::util::dumb_print(format_args!("Set nonblocking\n"));
unimplemented!();
/*
unsafe {
}
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!();
}
}
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!();
}
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
}
}
+ #[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;
}
}
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;
}
}
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;
/// 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 {
_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
// 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();
}
}
impl Handler {
pub unsafe fn new() -> Handler {
- unimplemented!();
+ Handler
}
}
}
pub unsafe fn cleanup() {
- unimplemented!();
+
}
start_thread(&*p as *const _ as *mut _);
+ ::sys_common::util::dumb_print(format_args!("thread\n"));
+
unimplemented!();
}
}
pub fn set_name(_name: &CStr) {
- unimplemented!();
+
}
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 }
impl Drop for Thread {
fn drop(&mut self) {
- panic!();
+ ::sys_common::util::dumb_print(format_args!("Thread::drop"));
+ unimplemented!();
}
}
#![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);
+ }
}