diff options
| author | Jeremy Soller <jackpot51@gmail.com> | 2016-10-27 20:57:49 -0600 |
|---|---|---|
| committer | Jeremy Soller <jackpot51@gmail.com> | 2016-10-27 20:57:49 -0600 |
| commit | 8b09e01fef9912e7c3eef997c40f9f4f91d09e4c (patch) | |
| tree | ab28c5cd1bb526809e12e316ea2b3c2135f72f28 /src/libstd/sys/redox/mutex.rs | |
| parent | 07436946b6ee6345509b73c6e4dafb38b6a243f1 (diff) | |
| download | rust-8b09e01fef9912e7c3eef997c40f9f4f91d09e4c.tar.gz rust-8b09e01fef9912e7c3eef997c40f9f4f91d09e4c.zip | |
Add redox system
Diffstat (limited to 'src/libstd/sys/redox/mutex.rs')
| -rw-r--r-- | src/libstd/sys/redox/mutex.rs | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/libstd/sys/redox/mutex.rs b/src/libstd/sys/redox/mutex.rs new file mode 100644 index 00000000000..5723443785a --- /dev/null +++ b/src/libstd/sys/redox/mutex.rs @@ -0,0 +1,125 @@ +use cell::UnsafeCell; +use intrinsics::{atomic_cxchg, atomic_xchg}; +use ptr; + +use libc::{futex, FUTEX_WAIT, FUTEX_WAKE}; + +pub unsafe fn mutex_try_lock(m: *mut i32) -> bool { + atomic_cxchg(m, 0, 1).0 == 0 +} + +pub unsafe fn mutex_lock(m: *mut i32) { + let mut c = 0; + //Set to larger value for longer spin test + for _i in 0..100 { + c = atomic_cxchg(m, 0, 1).0; + if c == 0 { + break; + } + //cpu_relax() + } + if c == 1 { + c = atomic_xchg(m, 2); + } + while c != 0 { + let _ = futex(m, FUTEX_WAIT, 2, 0, ptr::null_mut()); + c = atomic_xchg(m, 2); + } +} + +pub unsafe fn mutex_unlock(m: *mut i32) { + if *m == 2 { + *m = 0; + } else if atomic_xchg(m, 0) == 1 { + return; + } + //Set to larger value for longer spin test + for _i in 0..100 { + if *m != 0 { + if atomic_cxchg(m, 1, 2).0 != 0 { + return; + } + } + //cpu_relax() + } + let _ = futex(m, FUTEX_WAKE, 1, 0, ptr::null_mut()); +} + +pub struct Mutex { + pub lock: UnsafeCell<i32>, +} + +impl Mutex { + /// Create a new mutex. + pub const fn new() -> Self { + Mutex { + lock: UnsafeCell::new(0), + } + } + + pub unsafe fn init(&self) { + + } + + /// Try to lock the mutex + pub unsafe fn try_lock(&self) -> bool { + mutex_try_lock(self.lock.get()) + } + + /// Lock the mutex + pub unsafe fn lock(&self) { + mutex_lock(self.lock.get()); + } + + /// Unlock the mutex + pub unsafe fn unlock(&self) { + mutex_unlock(self.lock.get()); + } + + pub unsafe fn destroy(&self) { + + } +} + +unsafe impl Send for Mutex {} + +unsafe impl Sync for Mutex {} + +pub struct ReentrantMutex { + pub lock: UnsafeCell<i32>, +} + +impl ReentrantMutex { + pub const fn uninitialized() -> Self { + ReentrantMutex { + lock: UnsafeCell::new(0), + } + } + + pub unsafe fn init(&mut self) { + + } + + /// Try to lock the mutex + pub unsafe fn try_lock(&self) -> bool { + mutex_try_lock(self.lock.get()) + } + + /// Lock the mutex + pub unsafe fn lock(&self) { + mutex_lock(self.lock.get()); + } + + /// Unlock the mutex + pub unsafe fn unlock(&self) { + mutex_unlock(self.lock.get()); + } + + pub unsafe fn destroy(&self) { + + } +} + +unsafe impl Send for ReentrantMutex {} + +unsafe impl Sync for ReentrantMutex {} |
